diff options
256 files changed, 4727 insertions, 4038 deletions
diff --git a/dist/changes-4.4.1.md b/dist/changes-4.4.1.md new file mode 100644 index 0000000000..9e991cbb1b --- /dev/null +++ b/dist/changes-4.4.1.md @@ -0,0 +1,66 @@ +Qt Creator version 4.4.1 contains bug fixes. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline v4.4.0..v4.4.1 + +FakeVim + +* Fixed recognition of shortened `tabnext` and `tabprevious` commands + (QTCREATORBUG-18843) + +All Projects + +* Fixed `Add Existing Files` for top-level project nodes (QTCREATORBUG-18896) + +C++ Support + +* Improved handling of parsing failures (QTCREATORBUG-18864) +* Fixed crash with invalid raw string literal (QTCREATORBUG-18941) +* Fixed that code model did not use sysroot as reported from the build system + (QTCREATORBUG-18633) +* Fixed highlighting of `float` in C files (QTCREATORBUG-18879) +* Fixed `Convert to Camel Case` (QTCREATORBUG-18947) + +Debugging + +* Fixed that custom `solib-search-path` startup commands were ignored + (QTCREATORBUG-18812) +* Fixed `Run in terminal` when debugging external application + (QTCREATORBUG-18912) +* Fixed pretty printing of `CHAR` and `WCHAR` + +Clang Static Analyzer + +* Fixed options passed to analyzer on Windows + +Qt Quick Designer + +* Fixed usage of `shift` modifier when reparenting layouts + +SCXML Editor + +* Fixed eventless transitions (QTCREATORBUG-18345) + +Test Integration + +* Fixed test result output when debugging + +Platform Specific + +Windows + +* Fixed auto-detection of CMake 3.9 and later + +Android + +* Fixed issues with new Android SDK (26.1.1) (QTCREATORBUG-18962) +* Fixed search path for QML modules when debugging + +QNX + +* Fixed debugging (QTCREATORBUG-18804, QTCREATORBUG-17901) +* Fixed QML profiler startup (QTCREATORBUG-18954) diff --git a/dist/changes-4.5.0.md b/dist/changes-4.5.0.md new file mode 100644 index 0000000000..88c2bcfdc3 --- /dev/null +++ b/dist/changes-4.5.0.md @@ -0,0 +1,154 @@ +Qt Creator version 4.5 contains bug fixes and new features. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline origin/4.4..v4.5.0 + +General + +* Implemented "fuzzy" camel case lookup similar to code completion for locator + (QTCREATORBUG-3111) +* Changed `File System` pane to tree view with top level directory selectable + from `Computer`, `Home`, `Projects`, and individual project root directories + (QTCREATORBUG-8305) + +Editing + +* Added shortcut for sorting selected lines + +All Projects + +* Added progress indicator to project tree while project is parsed +* Added support for changing the maximum number of lines shown in compile output + (QTCREATORBUG-2200) + +CMake Projects + +* Added groups to CMake configuration UI +* Added option to change configuration variable types +* Fixed that value was removed when renaming configuration variable + (QTCREATORBUG-17926) + +C++ Support + +* Fixed lookup of functions that differ only in const-ness of arguments + (QTCREATORBUG-18475) +* Fixed detection of macros defined by tool chain for `C` +* Fixed that `Refactoring` context menu blocked UI while checking for available + actions +* Clang Code Model + * Added sanity check to `Clang Code Model Warnings` option + (QTCREATORBUG-18864) + * Fixed completion in `std::make_unique` and `std::make_shared` constructors + (QTCREATORBUG-18615) + * Fixed that function argument completion switched selected overload back to + default after typing comma (QTCREATORBUG-11688) +* GCC + * Improved auto-detection to include versioned binaries and cross-compilers + +QML Support + +* Added wizards with different starting UI layouts + +Python Support + +* Added simple code folding + +Debugging + +* Changed pretty printing of `QFlags` and bitfields to hexadecimal +* Fixed `Run in terminal` for debugging external application + (QTCREATORBUG-18912) +* LLDB / macOS + * Added pretty printing of Core Foundation and Foundation string-like types + (QTCREATORBUG-18638) + +QML Profiler + +* Improved robustness when faced with invalid data + +Qt Quick Designer + +* Added option to only show visible items in navigator + +Version Control Systems + +* Added query for saving modified files before opening commit editor + (QTCREATORBUG-3857) + +Beautifier + +* Clang Format + * Added action `Disable Formatting for Selected Text` + * Changed formatting without selection to format the syntactic entity + around the cursor + +Model Editor + +* Added support for custom relations + +SCXML Editor + +* Fixed crash after warnings are removed + +Platform Specific + +Windows + +* Fixed that environment variable keys were converted to upper case in build + and run configurations (QTCREATORBUG-18915) + +macOS + +* Fixed several issues when using case sensitive file systems while `File system + case sensitivity` is set to `Case Insensitive` (QTCREATORBUG-17929, + QTCREATORBUG-18672, QTCREATORBUG-18678) + +Android + +* Removed support for local deployment (QTBUG-62995) +* Removed support for Ant +* Improved checks for minimum requirements of Android tools (QTCREATORBUG-18837) + +Universal Windows Platform + +* Fixed deployment on Windows 10 Phone emulator + +Credits for these changes go to: +Alessandro Portale +Alexander Volkov +Andre Hartmann +André Pönitz +Christian Kandeler +Christian Stenger +Claus Steuer +Daniel Trevitz +David Schulz +Eike Ziller +Friedemann Kleint +Ivan Donchevskii +Jake Petroules +Jaroslaw Kobus +Jochen Becher +Knud Dollereder +Laurent Montel +Marco Benelli +Marco Bubke +Mitch Curtis +Nikita Baryshnikov +Nikolai Kosjar +Oliver Wolff +Orgad Shaneh +Robert Löhning +Ryuji Kakemizu +Samuel Gaist +Serhii Moroz +Thiago Macieira +Thomas Hartmann +Tim Jenssen +Tobias Hunger +Ulf Hermann +Vikas Pachdha diff --git a/qbs/modules/libclang/functions.js b/qbs/modules/libclang/functions.js index 5ad07af8fa..17d1bc4f9a 100644 --- a/qbs/modules/libclang/functions.js +++ b/qbs/modules/libclang/functions.js @@ -1,8 +1,8 @@ -var Environment = loadExtension("qbs.Environment") -var File = loadExtension("qbs.File") -var FileInfo = loadExtension("qbs.FileInfo") +var Environment = require("qbs.Environment") +var File = require("qbs.File") +var FileInfo = require("qbs.FileInfo") var MinimumLLVMVersion = "3.9.0" -var Process = loadExtension("qbs.Process") +var Process = require("qbs.Process") function readOutput(executable, args) { diff --git a/qbs/modules/qbsbuildconfig/qbsbuildconfig.qbs b/qbs/modules/qbsbuildconfig/qbsbuildconfig.qbs index a16eae5d41..492a6fe457 100644 --- a/qbs/modules/qbsbuildconfig/qbsbuildconfig.qbs +++ b/qbs/modules/qbsbuildconfig/qbsbuildconfig.qbs @@ -4,6 +4,8 @@ import qbs.FileInfo Module { Depends { name: "qtc" } + property bool priority: 1 // TODO: Remove declaration after 1.11 is out. + property bool enableUnitTests: false property bool enableProjectFileUpdates: true property bool installApiHeaders: false diff --git a/qbs/modules/qtc/qtc.js b/qbs/modules/qtc/qtc.js index 7183592b7b..375841af4e 100644 --- a/qbs/modules/qtc/qtc.js +++ b/qbs/modules/qtc/qtc.js @@ -1,6 +1,6 @@ -var File = loadExtension("qbs.File"); -var FileInfo = loadExtension("qbs.FileInfo"); -var TextFile = loadExtension("qbs.TextFile"); +var File = require("qbs.File"); +var FileInfo = require("qbs.FileInfo"); +var TextFile = require("qbs.TextFile"); function getExportBlock(productFile) { diff --git a/qtcreator.qbs b/qtcreator.qbs index 97ed38a468..41f5ad23ca 100644 --- a/qtcreator.qbs +++ b/qtcreator.qbs @@ -4,7 +4,7 @@ import qbs.FileInfo Project { name: "Qt Creator" - minimumQbsVersion: "1.7.0" + minimumQbsVersion: "1.8.0" property string minimumMacosVersion: "10.8" property bool withAutotests: qbs.buildVariant === "debug" property path ide_source_tree: path diff --git a/scripts/createDevPackage.py b/scripts/createDevPackage.py index 05577438f9..2bd898a9bd 100755 --- a/scripts/createDevPackage.py +++ b/scripts/createDevPackage.py @@ -67,6 +67,7 @@ source_include_patterns = [ r"^doc/.*$", # include everything under doc/ r"^.*\.pri$", # .pri files in all directories that are looked into r"^.*\.h$", # .h files in all directories that are looked into + r"^.*\.hpp$" # .hpp files in all directories that are looked into ] build_include_patterns = [ diff --git a/src/libs/glsl/glsl.g b/src/libs/glsl/glsl.g index e5fff79691..ccd80ae8f1 100644 --- a/src/libs/glsl/glsl.g +++ b/src/libs/glsl/glsl.g @@ -321,7 +321,7 @@ private: inline int consumeToken() { if (_index < int(_tokens.size())) return _index++; - return _tokens.size() - 1; + return static_cast<int>(_tokens.size()) - 1; } inline const Token &tokenAt(int index) const { if (index == 0) @@ -468,30 +468,30 @@ Parser::Parser(Engine *engine, const char *source, unsigned size, int variant) switch (tk.kind) { case T_LEFT_PAREN: - parenStack.push(_tokens.size()); + parenStack.push(static_cast<int>(_tokens.size())); break; case T_LEFT_BRACKET: - bracketStack.push(_tokens.size()); + bracketStack.push(static_cast<int>(_tokens.size())); break; case T_LEFT_BRACE: - braceStack.push(_tokens.size()); + braceStack.push(static_cast<int>(_tokens.size())); break; case T_RIGHT_PAREN: if (! parenStack.empty()) { - _tokens[parenStack.top()].matchingBrace = _tokens.size(); + _tokens[parenStack.top()].matchingBrace = static_cast<int>(_tokens.size()); parenStack.pop(); } break; case T_RIGHT_BRACKET: if (! bracketStack.empty()) { - _tokens[bracketStack.top()].matchingBrace = _tokens.size(); + _tokens[bracketStack.top()].matchingBrace = static_cast<int>(_tokens.size()); bracketStack.pop(); } break; case T_RIGHT_BRACE: if (! braceStack.empty()) { - _tokens[braceStack.top()].matchingBrace = _tokens.size(); + _tokens[braceStack.top()].matchingBrace = static_cast<int>(_tokens.size()); braceStack.pop(); } break; @@ -519,9 +519,13 @@ AST *Parser::parse(int startToken) _recovered = false; _tos = -1; _startToken.kind = startToken; + int recoveryAttempts = 0; + do { - again: + recoveryAttempts = 0; + + againAfterRecovery: if (unsigned(++_tos) == _stateStack.size()) { _stateStack.resize(_tos * 2); _locationStack.resize(_tos * 2); @@ -564,6 +568,7 @@ AST *Parser::parse(int startToken) reduce(ruleno); action = nt_action(_stateStack[_tos], lhs[ruleno] - TERMINAL_COUNT); } else if (action == 0) { + ++recoveryAttempts; const int line = _tokens[yyloc].line + 1; QString message = QLatin1String("Syntax error"); if (yytoken != -1) { @@ -574,7 +579,7 @@ AST *Parser::parse(int startToken) for (; _tos; --_tos) { const int state = _stateStack[_tos]; - static int tks[] = { + static int tks1[] = { T_RIGHT_BRACE, T_RIGHT_PAREN, T_RIGHT_BRACKET, T_SEMICOLON, T_COLON, T_COMMA, T_NUMBER, T_TYPE_NAME, T_IDENTIFIER, @@ -582,6 +587,16 @@ AST *Parser::parse(int startToken) T_WHILE, 0 }; + static int tks2[] = { + T_RIGHT_BRACE, T_RIGHT_PAREN, T_RIGHT_BRACKET, + T_SEMICOLON, T_COLON, T_COMMA, + 0 + }; + int *tks; + if (recoveryAttempts < 2) + tks = tks1; + else + tks = tks2; // Avoid running into an endless loop for e.g.: for(int x=0; x y for (int *tptr = tks; *tptr; ++tptr) { const int next = t_action(state, *tptr); @@ -604,7 +619,7 @@ AST *Parser::parse(int startToken) yytoken = -1; action = next; - goto again; + goto againAfterRecovery; } } } diff --git a/src/libs/glsl/glslparser.cpp b/src/libs/glsl/glslparser.cpp index 6d8401531e..a746a6050b 100644 --- a/src/libs/glsl/glslparser.cpp +++ b/src/libs/glsl/glslparser.cpp @@ -1,5 +1,5 @@ -#line 423 "./glsl.g" +#line 413 "./glsl.g" /**************************************************************************** ** @@ -109,9 +109,13 @@ AST *Parser::parse(int startToken) _recovered = false; _tos = -1; _startToken.kind = startToken; + int recoveryAttempts = 0; + do { - again: + recoveryAttempts = 0; + + againAfterRecovery: if (unsigned(++_tos) == _stateStack.size()) { _stateStack.resize(_tos * 2); _locationStack.resize(_tos * 2); @@ -154,6 +158,7 @@ AST *Parser::parse(int startToken) reduce(ruleno); action = nt_action(_stateStack[_tos], lhs[ruleno] - TERMINAL_COUNT); } else if (action == 0) { + ++recoveryAttempts; const int line = _tokens[yyloc].line + 1; QString message = QLatin1String("Syntax error"); if (yytoken != -1) { @@ -164,7 +169,7 @@ AST *Parser::parse(int startToken) for (; _tos; --_tos) { const int state = _stateStack[_tos]; - static int tks[] = { + static int tks1[] = { T_RIGHT_BRACE, T_RIGHT_PAREN, T_RIGHT_BRACKET, T_SEMICOLON, T_COLON, T_COMMA, T_NUMBER, T_TYPE_NAME, T_IDENTIFIER, @@ -172,6 +177,16 @@ AST *Parser::parse(int startToken) T_WHILE, 0 }; + static int tks2[] = { + T_RIGHT_BRACE, T_RIGHT_PAREN, T_RIGHT_BRACKET, + T_SEMICOLON, T_COLON, T_COMMA, + 0 + }; + int *tks; + if (recoveryAttempts < 2) + tks = tks1; + else + tks = tks2; // Avoid running into an endless loop for e.g.: for(int x=0; x y for (int *tptr = tks; *tptr; ++tptr) { const int next = t_action(state, *tptr); @@ -194,7 +209,7 @@ AST *Parser::parse(int startToken) yytoken = -1; action = next; - goto again; + goto againAfterRecovery; } } } diff --git a/src/libs/glsl/glslparser.h b/src/libs/glsl/glslparser.h index 7b44f2870f..f0ccf82cb9 100644 --- a/src/libs/glsl/glslparser.h +++ b/src/libs/glsl/glslparser.h @@ -1,5 +1,5 @@ -#line 215 "./glsl.g" +#line 210 "./glsl.g" /**************************************************************************** ** diff --git a/src/libs/glsl/glslparsertable.cpp b/src/libs/glsl/glslparsertable.cpp index 75a3521ce9..67666dba7e 100644 --- a/src/libs/glsl/glslparsertable.cpp +++ b/src/libs/glsl/glslparsertable.cpp @@ -3,8 +3,9 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of Qt Creator. +** This file is part of the Qt Toolkit. ** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -21,6 +22,8 @@ ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** +** $QT_END_LICENSE$ +** ****************************************************************************/ // This file was generated by qlalr - DO NOT EDIT! @@ -29,1252 +32,1266 @@ QT_BEGIN_NAMESPACE const char *const GLSLParserTable::spell [] = { - "end of file", "feed GLSL", "feed expression", "+=", "&", "&=", "&&", "attribute", "!", "bool", - "break", "bvec2", "bvec3", "bvec4", "^", "case", "centroid", ":", ",", "const", - "continue", "-", "--", "default", "discard", "/=", "dmat2", "dmat2x2", "dmat2x3", "dmat2x4", - "dmat3", "dmat3x2", "dmat3x3", "dmat3x4", "dmat4", "dmat4x2", "dmat4x3", "dmat4x4", "do", ".", - "double", "dvec2", "dvec3", "dvec4", "else", "=", "==", "flat", "float", "for", - ">=", "highp", "identifier", "if", "in", "++", "inout", "int", "invariant", "isampler1D", - "isampler1DArray", "isampler2D", "isampler2DArray", "isampler2DMS", "isampler2DMSArray", "isampler2DRect", "isampler3D", "isamplerBuffer", "isamplerCube", "isamplerCubeArray", - "ivec2", "ivec3", "ivec4", "layout", "<", "<<=", "{", "[", "<<", "(", - "<=", "lowp", "mat2", "mat2x2", "mat2x3", "mat2x4", "mat3", "mat3x2", "mat3x3", "mat3x4", - "mat4", "mat4x2", "mat4x3", "mat4x4", "mediump", "%=", "*=", "!=", "noperspective", "number constant", - "|=", "||", "out", "patch", "%", "plus", "precision", "?", "return", ">", - ">>=", "}", "]", ">>", ")", "sample", "sampler1D", "sampler1DArray", "sampler1DArrayShadow", "sampler1DShadow", - "sampler2D", "sampler2DArray", "sampler2DArrayShadow", "sampler2DMS", "sampler2DMSArray", "sampler2DRect", "sampler2DRectShadow", "sampler2DShadow", "sampler3D", "samplerBuffer", - "samplerCube", "samplerCubeArray", "samplerCubeArrayShadow", "samplerCubeShadow", ";", "/", "smooth", "*", "struct", "subroutine", - "-=", "switch", "~", "type_name", "uint", "uniform", "usampler1D", "usampler1DArray", "usampler2D", "usampler2DArray", - "usampler2DMS", "usampler2DMSarray", "usampler2DRect", "usampler3D", "usamplerBuffer", "usamplerCube", "usamplerCubeArray", "uvec2", "uvec3", "uvec4", - "varying", "vec2", "vec3", "vec4", "|", "void", "while", "^=", "^^", "true", - "false", "preprocessor directive", "comment", "error", "reserved word"}; + "end of file", "feed GLSL", "feed expression", "+=", "&", "&=", "&&", "attribute", "!", "bool", + "break", "bvec2", "bvec3", "bvec4", "^", "case", "centroid", ":", ",", "const", + "continue", "-", "--", "default", "discard", "/=", "dmat2", "dmat2x2", "dmat2x3", "dmat2x4", + "dmat3", "dmat3x2", "dmat3x3", "dmat3x4", "dmat4", "dmat4x2", "dmat4x3", "dmat4x4", "do", ".", + "double", "dvec2", "dvec3", "dvec4", "else", "=", "==", "flat", "float", "for", + ">=", "highp", "identifier", "if", "in", "++", "inout", "int", "invariant", "isampler1D", + "isampler1DArray", "isampler2D", "isampler2DArray", "isampler2DMS", "isampler2DMSArray", "isampler2DRect", "isampler3D", "isamplerBuffer", "isamplerCube", "isamplerCubeArray", + "ivec2", "ivec3", "ivec4", "layout", "<", "<<=", "{", "[", "<<", "(", + "<=", "lowp", "mat2", "mat2x2", "mat2x3", "mat2x4", "mat3", "mat3x2", "mat3x3", "mat3x4", + "mat4", "mat4x2", "mat4x3", "mat4x4", "mediump", "%=", "*=", "!=", "noperspective", "number constant", + "|=", "||", "out", "patch", "%", "plus", "precision", "?", "return", ">", + ">>=", "}", "]", ">>", ")", "sample", "sampler1D", "sampler1DArray", "sampler1DArrayShadow", "sampler1DShadow", + "sampler2D", "sampler2DArray", "sampler2DArrayShadow", "sampler2DMS", "sampler2DMSArray", "sampler2DRect", "sampler2DRectShadow", "sampler2DShadow", "sampler3D", "samplerBuffer", + "samplerCube", "samplerCubeArray", "samplerCubeArrayShadow", "samplerCubeShadow", ";", "/", "smooth", "*", "struct", "subroutine", + "-=", "switch", "~", "type_name", "uint", "uniform", "usampler1D", "usampler1DArray", "usampler2D", "usampler2DArray", + "usampler2DMS", "usampler2DMSarray", "usampler2DRect", "usampler3D", "usamplerBuffer", "usamplerCube", "usamplerCubeArray", "uvec2", "uvec3", "uvec4", + "varying", "vec2", "vec3", "vec4", "|", "void", "while", "^=", "^^", "true", + "false", "preprocessor directive", "comment", "error", "reserved word" +}; const short GLSLParserTable::lhs [] = { - 176, 177, 177, 177, 177, 177, 179, 179, 179, 179, - 179, 179, 180, 181, 182, 182, 183, 183, 185, 185, - 184, 184, 186, 188, 188, 190, 190, 190, 190, 191, - 191, 191, 191, 192, 192, 192, 192, 193, 193, 193, - 194, 194, 194, 195, 195, 195, 195, 195, 196, 196, - 196, 197, 197, 198, 198, 199, 199, 200, 200, 201, - 201, 202, 202, 203, 203, 187, 187, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 178, 178, - 205, 206, 206, 206, 206, 206, 206, 206, 206, 207, - 213, 213, 215, 215, 214, 218, 218, 216, 216, 216, - 216, 220, 220, 220, 220, 221, 208, 208, 208, 208, - 208, 208, 208, 223, 223, 223, 223, 223, 223, 223, - 223, 217, 217, 225, 226, 226, 226, 227, 228, 228, - 229, 229, 219, 211, 211, 211, 211, 211, 211, 211, - 211, 230, 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 189, 189, 210, 210, 210, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 209, 209, 209, 232, - 232, 212, 212, 233, 233, 234, 234, 235, 235, 235, - 224, 236, 237, 237, 239, 239, 239, 239, 239, 239, - 239, 238, 238, 247, 247, 248, 248, 246, 246, 240, - 240, 241, 249, 249, 250, 250, 242, 251, 251, 243, - 243, 244, 244, 244, 252, 252, 254, 254, 253, 253, - 245, 245, 245, 245, 245, 255, 256, 256, 257, 257, - 257, 258, 222, 175, 175, 259}; + 176, 177, 177, 177, 177, 177, 179, 179, 179, 179, + 179, 179, 180, 181, 182, 182, 183, 183, 185, 185, + 184, 184, 186, 188, 188, 190, 190, 190, 190, 191, + 191, 191, 191, 192, 192, 192, 192, 193, 193, 193, + 194, 194, 194, 195, 195, 195, 195, 195, 196, 196, + 196, 197, 197, 198, 198, 199, 199, 200, 200, 201, + 201, 202, 202, 203, 203, 187, 187, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 178, 178, + 205, 206, 206, 206, 206, 206, 206, 206, 206, 207, + 213, 213, 215, 215, 214, 218, 218, 216, 216, 216, + 216, 220, 220, 220, 220, 221, 208, 208, 208, 208, + 208, 208, 208, 223, 223, 223, 223, 223, 223, 223, + 223, 217, 217, 225, 226, 226, 226, 227, 228, 228, + 229, 229, 219, 211, 211, 211, 211, 211, 211, 211, + 211, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 189, 189, 210, 210, 210, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 209, 209, 209, 232, + 232, 212, 212, 233, 233, 234, 234, 235, 235, 235, + 224, 236, 237, 237, 239, 239, 239, 239, 239, 239, + 239, 238, 238, 247, 247, 248, 248, 246, 246, 240, + 240, 241, 249, 249, 250, 250, 242, 251, 251, 243, + 243, 244, 244, 244, 252, 252, 254, 254, 253, 253, + 245, 245, 245, 245, 245, 255, 256, 256, 257, 257, + 257, 258, 222, 175, 175, 259 +}; const short GLSLParserTable::rhs [] = { - 1, 1, 1, 1, 1, 3, 1, 4, 1, 3, - 2, 2, 1, 1, 1, 3, 2, 2, 2, 1, - 2, 3, 2, 1, 1, 1, 2, 2, 2, 1, - 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, - 1, 3, 3, 1, 3, 3, 3, 3, 1, 3, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 5, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 1, 2, 2, 4, 6, 7, 9, 10, 2, 2, - 1, 1, 2, 3, 3, 2, 5, 3, 2, 3, - 2, 1, 1, 1, 1, 1, 1, 3, 5, 6, - 7, 8, 5, 1, 2, 4, 5, 6, 7, 4, - 2, 1, 2, 1, 1, 1, 1, 4, 1, 3, - 1, 3, 1, 1, 1, 2, 2, 1, 2, 3, - 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, - 2, 2, 2, 1, 1, 2, 1, 3, 4, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, - 4, 1, 2, 3, 4, 1, 3, 1, 3, 4, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 3, 1, 1, 2, 3, 1, 2, 1, - 2, 5, 3, 1, 1, 4, 7, 1, 1, 3, - 2, 5, 7, 6, 1, 1, 1, 1, 2, 3, - 2, 2, 2, 3, 2, 1, 1, 2, 1, 1, - 1, 2, 0, 2, 2, 2}; + 1, 1, 1, 1, 1, 3, 1, 4, 1, 3, + 2, 2, 1, 1, 1, 3, 2, 2, 2, 1, + 2, 3, 2, 1, 1, 1, 2, 2, 2, 1, + 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, + 1, 3, 3, 1, 3, 3, 3, 3, 1, 3, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 3, 1, 5, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 1, 2, 2, 4, 6, 7, 9, 10, 2, 2, + 1, 1, 2, 3, 3, 2, 5, 3, 2, 3, + 2, 1, 1, 1, 1, 1, 1, 3, 5, 6, + 7, 8, 5, 1, 2, 4, 5, 6, 7, 4, + 2, 1, 2, 1, 1, 1, 1, 4, 1, 3, + 1, 3, 1, 1, 1, 2, 2, 1, 2, 3, + 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, + 2, 2, 2, 1, 1, 2, 1, 3, 4, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, + 4, 1, 2, 3, 4, 1, 3, 1, 3, 4, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 1, 1, 2, 3, 1, 2, 1, + 2, 5, 3, 1, 1, 4, 7, 1, 1, 3, + 2, 5, 7, 6, 1, 1, 1, 1, 2, 3, + 2, 2, 2, 3, 2, 1, 1, 2, 1, 1, + 1, 2, 0, 2, 2, 2 +}; const short GLSLParserTable::action_default [] = { - 0, 0, 0, 0, 32, 165, 172, 173, 174, 31, - 0, 193, 196, 197, 198, 194, 199, 200, 201, 195, - 202, 203, 204, 162, 169, 170, 171, 4, 161, 247, - 1, 0, 163, 218, 222, 219, 223, 240, 243, 234, - 220, 237, 221, 224, 175, 176, 177, 0, 249, 181, - 184, 185, 186, 182, 187, 188, 189, 183, 190, 191, - 192, 248, 2, 30, 205, 212, 214, 209, 206, 213, - 215, 239, 242, 232, 233, 210, 207, 236, 208, 216, - 217, 211, 0, 33, 3, 246, 164, 225, 229, 226, - 230, 241, 244, 235, 227, 238, 228, 231, 178, 179, - 180, 166, 167, 168, 160, 41, 54, 79, 66, 52, - 56, 315, 9, 15, 20, 0, 0, 14, 0, 58, - 60, 64, 62, 38, 26, 0, 7, 49, 44, 245, - 24, 155, 157, 34, 0, 5, 28, 27, 0, 0, - 6, 80, 0, 0, 0, 143, 0, 142, 126, 146, - 141, 0, 127, 147, 0, 0, 125, 154, 144, 138, - 0, 135, 134, 252, 0, 0, 0, 148, 149, 145, - 0, 131, 129, 0, 0, 132, 0, 128, 130, 150, - 151, 152, 153, 137, 0, 139, 140, 136, 250, 253, - 0, 258, 256, 0, 0, 259, 81, 0, 34, 260, - 0, 255, 257, 0, 254, 0, 251, 0, 0, 40, - 0, 0, 0, 37, 36, 35, 39, 0, 53, 0, - 0, 50, 0, 0, 0, 0, 48, 0, 0, 42, - 43, 45, 47, 46, 51, 0, 55, 160, 21, 18, - 0, 17, 22, 23, 0, 57, 0, 59, 0, 0, - 63, 0, 61, 0, 0, 65, 12, 0, 11, 0, - 10, 16, 13, 0, 8, 156, 0, 158, 0, 159, - 72, 76, 70, 68, 74, 71, 69, 78, 75, 73, - 77, 0, 67, 29, 141, 0, 311, 310, 307, 306, - 114, 0, 309, 313, 92, 0, 0, 107, 314, 0, - 122, 121, 0, 0, 84, 308, 115, 0, 0, 95, - 261, 120, 116, 0, 0, 118, 117, 0, 119, 90, - 133, 103, 105, 104, 102, 93, 0, 313, 99, 101, - 106, 96, 0, 0, 97, 0, 98, 100, 106, 313, - 94, 0, 82, 312, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 280, 0, 0, 269, 263, - 262, 265, 0, 266, 0, 270, 271, 267, 264, 278, - 0, 268, 122, 302, 0, 290, 301, 291, 305, 0, - 0, 0, 0, 0, 293, 0, 296, 295, 313, 122, - 298, 0, 297, 285, 0, 0, 0, 299, 300, 0, - 274, 275, 294, 0, 0, 286, 123, 0, 0, 0, - 282, 284, 0, 283, 272, 0, 273, 279, 303, 0, - 304, 0, 0, 0, 313, 288, 289, 0, 287, 0, - 0, 0, 292, 281, 277, 0, 83, 108, 0, 0, - 113, 109, 0, 0, 111, 110, 0, 112, 0, 89, - 0, 0, 0, 0, 85, 0, 86, 0, 0, 87, - 0, 88, 316}; + 0, 0, 0, 0, 32, 165, 172, 173, 174, 31, + 0, 193, 196, 197, 198, 194, 199, 200, 201, 195, + 202, 203, 204, 162, 169, 170, 171, 4, 161, 247, + 1, 0, 163, 218, 222, 219, 223, 240, 243, 234, + 220, 237, 221, 224, 175, 176, 177, 0, 249, 181, + 184, 185, 186, 182, 187, 188, 189, 183, 190, 191, + 192, 248, 2, 30, 205, 212, 214, 209, 206, 213, + 215, 239, 242, 232, 233, 210, 207, 236, 208, 216, + 217, 211, 0, 33, 3, 246, 164, 225, 229, 226, + 230, 241, 244, 235, 227, 238, 228, 231, 178, 179, + 180, 166, 167, 168, 160, 41, 54, 79, 66, 52, + 56, 315, 9, 15, 20, 0, 0, 14, 0, 58, + 60, 64, 62, 38, 26, 0, 7, 49, 44, 245, + 24, 155, 157, 34, 0, 5, 28, 27, 0, 0, + 6, 80, 0, 0, 0, 143, 0, 142, 126, 146, + 141, 0, 127, 147, 0, 0, 125, 154, 144, 138, + 0, 135, 134, 252, 0, 0, 0, 148, 149, 145, + 0, 131, 129, 0, 0, 132, 0, 128, 130, 150, + 151, 152, 153, 137, 0, 139, 140, 136, 250, 253, + 0, 258, 256, 0, 0, 259, 81, 0, 34, 260, + 0, 255, 257, 0, 254, 0, 251, 0, 0, 40, + 0, 0, 0, 37, 36, 35, 39, 0, 53, 0, + 0, 50, 0, 0, 0, 0, 48, 0, 0, 42, + 43, 45, 47, 46, 51, 0, 55, 160, 21, 18, + 0, 17, 22, 23, 0, 57, 0, 59, 0, 0, + 63, 0, 61, 0, 0, 65, 12, 0, 11, 0, + 10, 16, 13, 0, 8, 156, 0, 158, 0, 159, + 72, 76, 70, 68, 74, 71, 69, 78, 75, 73, + 77, 0, 67, 29, 141, 0, 311, 310, 307, 306, + 114, 0, 309, 313, 92, 0, 0, 107, 314, 0, + 122, 121, 0, 0, 84, 308, 115, 0, 0, 95, + 261, 120, 116, 0, 0, 118, 117, 0, 119, 90, + 133, 103, 105, 104, 102, 93, 0, 313, 99, 101, + 106, 96, 0, 0, 97, 0, 98, 100, 106, 313, + 94, 0, 82, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 276, 280, 0, 0, 269, 263, + 262, 265, 0, 266, 0, 270, 271, 267, 264, 278, + 0, 268, 122, 302, 0, 290, 301, 291, 305, 0, + 0, 0, 0, 0, 293, 0, 296, 295, 313, 122, + 298, 0, 297, 285, 0, 0, 0, 299, 300, 0, + 274, 275, 294, 0, 0, 286, 123, 0, 0, 0, + 282, 284, 0, 283, 272, 0, 273, 279, 303, 0, + 304, 0, 0, 0, 313, 288, 289, 0, 287, 0, + 0, 0, 292, 281, 277, 0, 83, 108, 0, 0, + 113, 109, 0, 0, 111, 110, 0, 112, 0, 89, + 0, 0, 0, 0, 85, 0, 86, 0, 0, 87, + 0, 88, 316 +}; const short GLSLParserTable::goto_default [] = { - 3, 135, 126, 362, 124, 263, 112, 117, 113, 116, - 115, 114, 107, 118, 130, 133, 134, 123, 105, 128, - 127, 109, 106, 110, 119, 120, 122, 121, 108, 281, - 197, 360, 364, 296, 125, 131, 299, 205, 291, 293, - 294, 325, 290, 328, 327, 326, 329, 324, 297, 311, - 160, 159, 161, 173, 172, 162, 132, 129, 163, 203, - 192, 361, 369, 359, 368, 363, 367, 371, 358, 365, - 366, 370, 402, 400, 410, 390, 427, 388, 394, 391, - 298, 289, 288, 292, 0}; + 3, 135, 126, 362, 124, 263, 112, 117, 113, 116, + 115, 114, 107, 118, 130, 133, 134, 123, 105, 128, + 127, 109, 106, 110, 119, 120, 122, 121, 108, 281, + 197, 360, 364, 296, 125, 131, 299, 205, 291, 293, + 294, 325, 290, 328, 327, 326, 329, 324, 297, 311, + 160, 159, 161, 173, 172, 162, 132, 129, 163, 203, + 192, 361, 369, 359, 368, 363, 367, 371, 358, 365, + 366, 370, 402, 400, 410, 390, 427, 388, 394, 391, + 298, 289, 288, 292, 0 +}; const short GLSLParserTable::action_index [] = { - 96, 1153, 3162, 24, -175, -175, -175, -175, -175, -175, - 1153, -175, -175, -175, -175, -175, -175, -175, -175, -175, - -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, - -12, 1153, -175, -175, -175, -175, -175, -175, -175, -175, - -175, -175, -175, -175, -175, -175, -175, 1153, -175, -175, - -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, - -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, - -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, - -175, -175, 47, -175, -175, -175, -175, -175, -175, -175, - -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, - -175, -175, -175, -175, -175, 85, 53, -175, -175, 65, - 55, 52, -175, -175, 1320, -51, 66, -175, -52, -158, - 154, -11, -157, 18, 94, 488, -175, 118, 31, -175, - -175, -175, -46, 183, 1153, -175, -175, -175, 71, 1153, - -175, -175, -58, 2490, 2490, -175, 77, -175, -175, -175, - 198, -65, -175, -175, 39, 32, -175, -175, -175, 322, - 200, 322, -175, -175, 2994, 654, -16, -175, -175, -175, - 7, 15, -175, 83, -31, -175, 21, -175, -175, -175, - -175, -175, -175, -175, 322, -175, -175, -175, -175, -175, - -5, -23, -175, 84, 1988, -175, -175, -63, -175, -175, - 4, -175, -175, 86, -175, 2826, -175, 1153, 1153, 28, - 1153, 1153, 1153, -175, -175, -175, 13, 1153, 61, 1153, - 1153, 93, 1153, 1153, 1153, 1153, 27, 1153, 1153, 64, - 73, 5, 17, 22, 101, 1153, 35, -64, -175, -175, - 1153, -175, -175, -175, 1153, 37, 1153, -116, 1153, 1153, - -115, 1153, 154, 74, 1153, -175, -175, 820, -175, 1153, - -39, -175, 19, -71, -175, -175, 1654, -175, -66, -175, - -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, - -175, 1153, -175, -175, 210, 78, -175, -175, -175, 3162, - 10, -53, -175, 147, 48, 11, 70, -175, -175, 986, - -175, -175, 488, -125, -175, -175, 75, 1153, 1487, -175, - -175, -175, -41, -110, 1153, -175, -17, 1153, -175, -175, - -175, -175, -175, -175, -175, -175, 654, 54, -175, -175, - -36, -57, 1153, -89, -175, 654, -175, -175, -33, 128, - -175, 4170, -175, -175, -117, 1153, -109, 12, -124, 3666, - -74, -67, 4506, 1821, -175, -175, -78, -15, -175, -175, - -175, -175, 62, -175, -90, -175, -175, -175, -175, -175, - 4338, -175, -27, -175, 58, -175, -175, -175, -175, -121, - -37, 1153, 63, -62, -175, 3498, -175, -175, 3330, -14, - -175, -131, -175, 16, -79, -19, 654, 1153, 8, 3834, - -175, -175, -175, -24, 1153, -175, -175, 1153, 60, 3666, - -175, -1, 3666, -175, -175, 4002, -175, -175, -175, 59, - -175, 1153, 56, -68, 3666, -175, 3666, -111, -175, 3330, - -84, 3834, -175, -175, -175, 3, -175, 26, 1153, 2322, - -175, -13, -97, 1153, -175, -32, 1153, -175, -69, -175, - 2490, 2658, 30, 2, -175, 2155, -175, -96, -54, -175, - -112, -175, -175, + 86, 1180, 3189, 58, -175, -175, -175, -175, -175, -175, + 1180, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -79, 1180, -175, -175, -175, -175, -175, -175, -175, -175, + -175, -175, -175, -175, -175, -175, -175, 1180, -175, -175, + -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -175, -175, 32, -175, -175, -175, -175, -175, -175, -175, + -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -175, -175, -175, -175, -175, 82, 61, -175, -175, 60, + 181, 45, -175, -175, 1347, -55, 87, -175, -25, -113, + -3, 6, -159, 40, 128, 515, -175, 112, 26, -175, + -175, -175, -58, 197, 1180, -175, -175, -175, 84, 1180, + -175, -175, -62, 2517, 2517, -175, 56, -175, -175, -175, + 187, -54, -175, -175, 46, 25, -175, -175, -175, 349, + 207, 349, -175, -175, 2685, 681, 10, -175, -175, -175, + 3, 11, -175, 83, -38, -175, 0, -175, -175, -175, + -175, -175, -175, -175, 349, -175, -175, -175, -175, -175, + 18, -6, -175, 79, 1514, -175, -175, -77, -175, -175, + -16, -175, -175, 76, -175, 3021, -175, 1180, 1180, 12, + 1180, 1180, 1180, -175, -175, -175, 37, 1180, 49, 1180, + 1180, 90, 1180, 1180, 1180, 1180, 15, 1180, 1180, 71, + 68, -4, 8, 7, 80, 1180, 33, -75, -175, -175, + 1180, -175, -175, -175, 1180, 181, 1180, -132, 1180, 1180, + -137, 1180, 34, 73, 1180, -175, -175, 847, -175, 1180, + -10, -175, 48, -44, -175, -175, 2349, -175, -45, -175, + -175, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -175, 1180, -175, -175, 217, 72, -175, -175, -175, 3189, + -47, -107, -175, 163, -14, 22, 81, -175, -175, 1013, + -175, -175, 515, -105, -175, -175, 66, 1180, 2015, -175, + -175, -175, -21, -91, 1180, -175, -34, 1180, -175, -175, + -175, -175, -175, -175, -175, -175, 681, 63, -175, -175, + -40, -76, 1180, -78, -175, 681, -175, -175, 5, 105, + -175, 4365, -175, -175, -81, 1180, -121, -2, -114, 3861, + -56, -53, 4533, 2182, -175, -175, -57, -69, -175, -175, + -175, -175, 54, -175, -74, -175, -175, -175, -175, -175, + 4029, -175, -46, -175, 59, -175, -175, -175, -175, -128, + -49, 1180, 55, -93, -175, 3525, -175, -175, 3357, -37, + -175, -90, -175, 27, -68, -5, 681, 1180, 30, 3693, + -175, -175, -175, 4, 1180, -175, -175, 1180, 57, 3861, + -175, -1, 3861, -175, -175, 4197, -175, -175, -175, 62, + -175, 1180, 64, 20, 3861, -175, 3861, -103, -175, 3357, + -86, 3693, -175, -175, -175, -35, -175, 38, 1180, 1848, + -175, -27, -85, 1180, -175, -43, 1180, -175, -70, -175, + 2517, 2853, 29, 1, -175, 1681, -175, -84, -48, -175, + -118, -175, -175, - -85, 68, 99, -85, -85, -85, -85, -85, -85, -85, - 0, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -4, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -2, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, 22, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, 3, -85, -85, -85, -85, - -85, -85, -85, -85, 6, -85, -85, -85, -85, 21, - -85, -85, -85, 60, 131, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -35, - 37, -18, -85, -85, 86, -11, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -45, -85, -85, -85, - -85, -85, -85, -85, -51, -85, -85, -85, -85, -85, - -49, -85, -85, -85, 34, -85, -85, -85, -85, -85, - -48, -85, -85, -85, -85, 114, -85, 39, 36, -85, - -8, -1, -9, -85, -85, -85, -85, 24, -85, 26, - 35, -85, 71, 78, 84, 72, -85, 45, 49, -85, - -85, -85, -85, -85, -85, 79, -85, -85, -85, -85, - -10, -85, -85, -85, 83, -85, 58, -85, 50, 33, - -85, 44, -85, -85, 16, -85, -85, 11, -85, 19, - -85, -85, -85, -85, -85, -85, 106, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, 13, -85, -85, -85, -7, -85, -85, -85, 210, - -85, -85, -85, -85, -85, -38, -85, -85, -85, 17, - -85, -85, -3, -85, -85, -85, -85, 4, 87, -85, - -85, -85, -85, -85, 30, -85, -85, 31, -85, -85, - -85, -85, -85, -85, -85, -85, 15, -27, -85, -85, - -85, -85, 109, -85, -85, 115, -85, -85, -85, -17, - -85, 12, -85, -85, -85, 20, -85, -85, -85, 64, - -85, -85, 139, 14, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - 52, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, 27, -85, -85, -85, 90, -85, -85, 135, -85, - -85, -85, -85, -85, -85, -85, -14, 2, -85, 56, - -85, -85, -85, -85, 46, -85, -85, 5, -85, 54, - -85, -85, 47, -85, -85, 61, -85, -85, -85, -85, - -85, 10, -85, -85, 105, -85, 43, -85, -85, 156, - -85, 93, -85, -85, -85, -85, -85, -85, 32, 118, - -85, -85, -85, 40, -85, -85, 28, -85, -85, -85, - 104, 96, -85, -85, -85, 97, -85, -85, -85, -85, - -85, -85, -85}; + -85, 11, 90, -85, -85, -85, -85, -85, -85, -85, + -3, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -9, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, 70, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, 20, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, 3, -85, -85, -85, -85, + -85, -85, -85, -85, 9, -85, -85, -85, -85, 5, + -85, -85, -85, 56, 110, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -39, + 21, -21, -85, -85, 96, -7, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -49, -85, -85, -85, + -85, -85, -85, -85, -47, -85, -85, -85, -85, -85, + -46, -85, -85, -85, 35, -85, -85, -85, -85, -85, + -45, -85, -85, -85, -85, 109, -85, 29, 30, -85, + -4, -5, -6, -85, -85, -85, -85, 38, -85, 40, + 41, -85, 43, 78, 84, 81, -85, 80, 66, -85, + -85, -85, -85, -85, -85, 67, -85, -85, -85, -85, + -12, -85, -85, -85, 42, -85, 51, -85, 52, 27, + -85, 49, -85, -85, 24, -85, -85, 18, -85, 22, + -85, -85, -85, -85, -85, -85, 114, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, 6, -85, -85, -85, -11, -85, -85, -85, 129, + -85, -85, -85, -85, -85, -38, -85, -85, -85, 23, + -85, -85, -2, -85, -85, -85, -85, 19, 79, -85, + -85, -85, -85, -85, 39, -85, -85, 37, -85, -85, + -85, -85, -85, -85, -85, -85, 14, -18, -85, -85, + -85, -85, 121, -85, -85, 94, -85, -85, -85, -19, + -85, 7, -85, -85, -85, 16, -85, -85, -85, 77, + -85, -85, 87, 17, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + 65, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, 26, -85, -85, -85, 91, -85, -85, 159, -85, + -85, -85, -85, -85, -85, -85, -13, -1, -85, 54, + -85, -85, -85, -85, 57, -85, -85, 1, -85, 69, + -85, -85, 141, -85, -85, 76, -85, -85, -85, -85, + -85, 0, -85, -85, 88, -85, 25, -85, -85, 223, + -85, 100, -85, -85, -85, -85, -85, -85, 36, 138, + -85, -85, -85, 31, -85, -85, 28, -85, -85, -85, + 97, 105, -85, -85, -85, 98, -85, -85, -85, -85, + -85, -85, -85 +}; const short GLSLParserTable::action_info [] = { - 428, 421, 316, 397, 314, 385, 244, 450, 424, 304, - 378, 251, 407, 446, 170, 445, 331, 373, 144, 331, - 332, 404, 461, 334, 462, 376, 139, 243, 317, 377, - 431, 266, 443, 403, 139, 399, 191, 139, 459, 217, - -25, 264, 381, 412, 342, 380, 269, 191, 244, 199, - -19, 235, -24, 251, 194, 437, 191, 217, 460, 171, - 174, 319, 306, 239, 429, -24, 339, -25, 175, 235, - 139, 438, 384, 171, 139, 375, 139, 139, 139, 455, - 139, 139, 453, 227, 240, 207, 181, 341, 435, 139, - 248, 254, 139, 179, 207, 227, 249, 2, 1, 142, - 227, 176, 200, 439, 200, 227, 207, 219, 321, 227, - 322, 219, 0, 0, 0, 0, 256, 210, 228, 0, - 307, 0, 210, 143, 0, 0, 0, 0, 0, 29, - 228, 167, 210, 257, 182, 228, 456, 0, 0, 0, - 228, 180, 0, 222, 228, 342, 0, 320, 211, 258, - 212, 222, 308, 211, 309, 212, 323, 0, 220, 48, - 246, 0, 220, 211, 454, 212, 320, 223, 222, 208, - 423, 259, 61, 224, 409, 223, 0, 383, 208, 168, - 241, 224, 321, 0, 322, 140, 270, 0, 271, 0, - 208, 0, 223, 420, 0, 0, 433, 177, 224, 0, - 0, 321, 225, 322, 436, -124, 0, 145, 272, 0, - 225, 0, 0, 0, -124, 0, 146, -124, 201, 147, - 204, 0, 0, 0, 0, 0, -124, 225, 273, -124, - 323, 0, 0, 0, 0, 0, 0, 169, 0, 0, - 0, 0, 0, 0, 0, -124, 0, 148, 0, 323, - 0, 0, -124, 0, 149, 0, 0, -124, 274, 0, - 0, -91, 301, 0, -124, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 275, 276, - 0, 0, 0, 277, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 278, 0, 0, -124, 0, 152, 0, - -124, -124, 153, 154, 0, 0, 0, 0, -124, 0, - 0, 0, -124, -124, 0, 155, 0, 0, 0, 0, - 0, 0, 0, 279, 0, -124, 0, 0, 0, 145, - 0, 0, 0, 0, -124, 0, 156, 0, 146, 0, - 0, 147, 0, -124, 0, 157, -124, 0, 0, 0, - 280, 0, 0, 0, 0, -124, 0, 0, -124, 0, - 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -124, 0, 0, 0, 0, 0, 149, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 153, 154, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 155, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, - 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 23, 24, - 25, 26, 0, 0, 0, 0, 28, 0, 0, 0, - 0, 0, 0, 0, 0, 32, 0, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 0, 0, 0, 0, 82, 0, 0, 0, - 0, 85, 86, 0, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, - 102, 103, 0, 104, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 0, 6, 7, 8, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 23, 24, 25, 26, 0, 0, - 0, 0, 28, 0, 0, 29, 0, 0, 0, 0, - 0, 32, 0, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 0, 0, - 0, 0, 82, 0, 0, 0, 0, 85, 86, 0, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 0, 101, 102, 103, 0, 104, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, - 23, 24, 25, 26, 0, 0, 0, 0, 28, 0, - 0, 29, 260, 0, 0, 0, 0, 32, 0, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, - 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 0, 0, 0, 0, 82, 0, - 0, 0, 0, 85, 86, 0, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 0, 101, 102, 103, 0, 104, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 6, 7, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 0, 23, 24, 25, 26, - 0, 0, 0, 0, 28, 0, 0, 29, 448, 0, - 0, 0, 0, 32, 0, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 449, 0, 0, 0, 82, 0, 0, 0, 0, 85, - 86, 0, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 0, 101, 102, 103, - 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 5, 0, 6, 7, 8, 0, 0, 0, - 0, 0, 0, 0, 9, 10, 0, 0, 0, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 0, 0, 23, 24, 25, 26, 0, 0, 0, - 0, 28, 0, 0, 29, 30, 0, 0, 31, 0, - 32, 0, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, - 0, 0, 47, 0, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, - 0, 0, 62, 0, 0, 0, 0, 0, 63, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 0, 0, 0, - 0, 82, 0, 0, 0, 83, 85, 86, 0, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 0, 101, 102, 103, 0, 104, 0, - 0, 0, 84, 27, 0, 0, 0, 0, 4, 5, - 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, - 0, 9, 10, 0, 0, 0, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, - 23, 24, 25, 26, 0, 0, 0, 0, 28, 0, - 0, 29, 30, 0, 0, 31, 0, 32, 0, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 0, 0, 0, 0, 0, 0, 47, - 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 0, 0, 0, 0, 62, - 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 0, 0, 0, 0, 82, 0, - 0, 0, 83, 85, 86, 0, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 0, 101, 102, 103, 0, 237, 0, 0, 0, 84, - 27, 0, 0, 0, 0, 4, 5, 0, 6, 7, - 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, - 0, 0, 0, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 0, 0, 23, 24, 25, - 26, 0, 0, 0, 0, 28, 0, 0, 29, 30, - 0, 0, 31, 0, 32, 0, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 0, 0, 0, 0, 0, 0, 47, 0, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 0, 0, 0, 0, 62, 0, 0, 0, - 0, 0, 63, 0, 0, 0, 0, 0, 0, 312, - 0, 0, 0, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 0, 0, 0, 0, 82, 0, 0, 0, 83, - 85, 86, 0, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, - 103, 0, 104, 0, 0, 0, 84, 27, 0, 0, - 0, 0, 4, 5, 0, 6, 7, 8, 0, 0, - 0, 0, 0, 0, 0, 9, 10, 0, 0, 0, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 23, 24, 25, 26, 0, 0, - 0, 0, 28, 0, 0, 29, 30, 0, 0, 31, - 0, 32, 0, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, - 0, 0, 0, 47, 0, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, - 0, 0, 0, 62, 0, 0, 0, 0, 0, 63, - 0, 0, 0, 0, 0, 0, 267, 0, 0, 0, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 0, 0, - 0, 0, 82, 0, 0, 0, 83, 85, 86, 0, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 0, 101, 102, 103, 0, 104, - 0, 0, 0, 84, 27, 0, 0, 0, 0, 4, - 5, 0, 6, 7, 8, 0, 0, 0, 0, 0, - 0, 0, 9, 10, 0, 0, 0, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, - 0, 23, 24, 25, 26, 0, 0, 0, 0, 28, - 0, 0, 29, 30, 0, 0, 31, 0, 32, 0, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, - 47, 0, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, - 62, 0, 0, 0, 0, 0, 63, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 418, 0, 0, 0, 82, - 0, 0, 0, 83, 85, 86, 0, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 0, 101, 102, 103, 0, 104, 0, 0, 0, - 84, 27, 0, 0, 0, 0, 4, 5, 0, 6, - 7, 8, 0, 0, 0, 0, 0, 0, 0, 9, - 10, 0, 0, 0, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 23, 24, - 25, 26, 0, 0, 0, 0, 28, 0, 0, 29, - 30, 0, 0, 31, 0, 32, 0, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 0, 0, 0, 0, 0, 0, 47, 0, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 0, 0, 0, 0, 62, 0, 0, - 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, - 195, 0, 0, 0, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 0, 0, 0, 0, 82, 0, 0, 0, - 83, 85, 86, 0, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, - 102, 103, 0, 104, 0, 0, 0, 84, 27, 0, - 0, 0, 0, 4, 5, 0, 6, 7, 8, 0, - 0, 0, 0, 0, 0, 0, 9, 10, 0, 0, - 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 0, 0, 23, 24, 25, 26, 0, - 0, 0, 0, 28, 0, 0, 29, 30, 0, 0, - 31, 0, 32, 0, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, - 0, 0, 0, 0, 47, 0, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, - 63, 0, 0, 0, 0, 0, 0, 457, 0, 0, - 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 0, - 0, 0, 0, 82, 0, 0, 0, 83, 85, 86, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, - 104, 0, 0, 0, 84, 27, 0, 0, 0, 0, - 4, 5, 0, 6, 7, 8, 0, 0, 0, 0, - 0, 0, 0, 9, 10, 0, 0, 0, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 0, 0, 23, 24, 25, 26, 0, 0, 0, 0, - 28, 0, 0, 29, 30, 0, 0, 31, 0, 32, - 0, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, - 0, 47, 0, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, - 0, 62, 0, 0, 0, 0, 0, 63, 0, 0, - 0, 0, 0, 0, 441, 0, 0, 0, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 0, 0, 0, 0, - 82, 0, 0, 0, 83, 85, 86, 0, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 0, 101, 102, 103, 0, 104, 0, 0, - 0, 84, 27, 0, 0, 0, 0, 145, 0, 5, - 0, 6, 7, 8, 0, 0, 146, 0, 0, 147, - 0, 0, 0, 0, 0, 0, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, - 23, 24, 25, 26, 0, 0, 0, 148, 28, 0, - 0, 29, 0, 0, 149, 0, 0, 32, 150, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 151, 0, 0, 0, 0, 0, 0, - 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 0, 0, 0, 152, 0, - 0, 0, 153, 154, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 155, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 0, 0, 156, 0, 82, 0, - 0, 0, 0, 85, 86, 157, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 158, 101, 102, 103, 0, 104, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 145, 0, 5, 0, 6, - 7, 8, 0, 0, 146, 0, 0, 147, 0, 0, - 0, 0, 0, 0, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 23, 24, - 25, 26, 0, 0, 0, 148, 28, 0, 0, 29, - 0, 0, 149, 0, 0, 32, 150, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 151, 0, 0, 0, 0, 0, 0, 0, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 0, 0, 0, 152, 0, 0, 0, - 153, 154, 0, 0, 0, 0, 0, 0, 0, 452, - 0, 0, 0, 155, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 0, 0, 156, 0, 82, 0, 0, 0, - 0, 85, 86, 157, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 158, 101, - 102, 103, 0, 104, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 145, 0, 5, 0, 6, 7, 8, - 0, 0, 146, 0, 0, 147, 0, 0, 0, 0, - 0, 0, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 0, 23, 24, 25, 26, - 0, 0, 0, 148, 28, 0, 0, 29, 0, 0, - 149, 0, 0, 32, 150, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 151, - 0, 0, 0, 0, 0, 0, 0, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 0, 0, 0, 152, 0, 0, 0, 153, 154, - 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, - 0, 155, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 0, 0, 156, 0, 82, 0, 0, 0, 0, 85, - 86, 157, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 158, 101, 102, 103, - 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 145, 0, 5, 0, 6, 7, 8, 0, 0, - 146, 0, 0, 147, 0, 0, 0, 0, 0, 0, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 23, 24, 25, 26, 0, 0, - 0, 148, 28, 0, 0, 29, 0, 0, 149, 0, - 0, 32, 150, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 151, 0, 0, - 0, 0, 0, 0, 0, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, - 0, 0, 152, 0, 0, 0, 153, 154, 0, 0, - 0, 0, 0, 0, 0, 188, 0, 0, 0, 155, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 0, 0, - 156, 0, 82, 0, 0, 0, 0, 85, 86, 157, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 158, 101, 102, 103, 0, 104, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, - 0, 5, 0, 6, 7, 8, 0, 0, 146, 0, - 0, 147, 0, 0, 0, 0, 0, 0, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 0, 0, 23, 24, 25, 26, 0, 0, 0, 148, - 28, 0, 0, 29, 0, 0, 149, 0, 0, 32, - 284, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 151, 0, 0, 0, 0, - 0, 0, 0, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, - 152, 0, 0, 0, 153, 154, 0, 0, 285, 0, - 0, 0, 0, 0, 0, 0, 0, 155, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 286, 0, 156, 0, - 82, 0, 0, 0, 0, 85, 86, 157, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 158, 101, 102, 103, 0, 104, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 145, 4, 5, - 0, 6, 7, 8, 0, 0, 146, 0, 0, 147, - 0, 9, 10, 0, 0, 0, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, - 23, 24, 25, 26, 0, 0, 0, 148, 28, 0, - 0, 29, 30, 0, 149, 31, 0, 32, 150, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 151, 0, 0, 0, 0, 0, 47, - 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 0, 0, 0, 152, 62, - 0, 0, 153, 154, 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 155, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 0, 0, 156, 0, 82, 0, - 0, 0, 83, 85, 86, 157, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 158, 101, 102, 103, 0, 104, 0, 0, 0, 84, - 27, 0, 0, 0, 0, 145, 4, 5, 0, 6, - 7, 8, 0, 0, 146, 0, 0, 147, 0, 9, - 10, 0, 0, 0, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 23, 24, - 25, 26, 0, 0, 0, 148, 28, 0, 0, 29, - 30, 0, 149, 31, 0, 32, 284, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 151, 0, 0, 0, 0, 0, 47, 0, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 0, 0, 0, 152, 62, 0, 0, - 153, 154, 0, 63, 285, 0, 0, 0, 0, 0, - 0, 0, 0, 155, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 355, 0, 156, 0, 82, 0, 0, 0, - 83, 85, 86, 157, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 158, 101, - 102, 103, 0, 104, 0, 0, 0, 84, 27, 0, - 0, 0, 0, 145, 4, 5, 344, 6, 7, 8, - 0, 345, 146, 0, 0, 147, 346, 9, 10, 347, - 348, 0, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 349, 0, 23, 24, 25, 26, - 0, 0, 0, 148, 28, 350, 0, 29, 30, 351, - 149, 31, 0, 32, 284, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 151, - 0, 0, 352, 0, 0, 47, 0, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 0, 0, 0, 152, 62, 0, 0, 153, 154, - 0, 63, 285, 0, 353, 0, 0, 0, 0, 0, - 0, 155, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 355, 0, 156, 0, 82, 0, 0, 356, 83, 85, - 86, 157, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 158, 101, 102, 103, - 0, 104, 357, 0, 0, 84, 27, 0, 0, 0, - 0, 145, 4, 5, 344, 6, 7, 8, 0, 345, - 146, 0, 0, 147, 346, 9, 10, 347, 348, 0, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 349, 0, 23, 24, 25, 26, 0, 0, - 0, 148, 28, 350, 0, 29, 30, 351, 149, 31, - 0, 32, 284, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 151, 0, 0, - 341, 0, 0, 47, 0, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, - 0, 0, 152, 62, 0, 0, 153, 154, 0, 63, - 285, 0, 353, 0, 0, 0, 0, 0, 0, 155, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 355, 0, - 156, 0, 82, 0, 0, 356, 83, 85, 86, 157, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 158, 101, 102, 103, 0, 104, - 357, 0, 0, 84, 27, 0, 0, 0, 0, 145, - 4, 5, 344, 6, 7, 8, 0, 345, 146, 0, - 0, 147, 346, 9, 10, 347, 348, 0, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 349, 0, 23, 24, 25, 26, 0, 0, 0, 148, - 28, 350, 0, 29, 30, 351, 149, 31, 0, 32, - 284, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 151, 0, 0, 352, 0, - 0, 47, 0, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, - 152, 62, 0, 0, 153, 154, 0, 63, 285, 0, - 353, 0, 0, 416, 0, 0, 0, 155, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 355, 0, 156, 0, - 82, 0, 0, 356, 83, 85, 86, 157, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 158, 101, 102, 103, 0, 104, 357, 0, - 0, 84, 27, 0, 0, 0, 0, 145, 4, 5, - 344, 6, 7, 8, 0, 345, 146, 0, 0, 147, - 346, 9, 10, 347, 348, 0, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 349, 0, - 23, 24, 25, 26, 0, 0, 0, 148, 28, 350, - 0, 29, 30, 351, 149, 31, 0, 32, 284, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 151, 0, 0, 352, 0, 0, 47, - 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 0, 0, 0, 152, 62, - 0, 0, 153, 154, 0, 63, 285, 0, 353, 0, - 0, 354, 0, 0, 0, 155, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 355, 0, 156, 0, 82, 0, - 0, 356, 83, 85, 86, 157, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 158, 101, 102, 103, 0, 104, 357, 0, 0, 84, - 27, 0, 0, 0, 0, 145, 4, 5, 344, 6, - 7, 8, 0, 345, 146, 0, 0, 147, 346, 9, - 10, 347, 348, 0, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 349, 0, 23, 24, - 25, 26, 0, 0, 0, 148, 28, 350, 0, 29, - 30, 351, 149, 31, 0, 32, 284, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 151, 0, 0, 352, 0, 0, 47, 0, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 0, 0, 0, 152, 62, 0, 0, - 153, 154, 0, 63, 285, 0, 353, 0, 0, 434, - 0, 0, 0, 155, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 355, 0, 156, 0, 82, 0, 0, 356, - 83, 85, 86, 157, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 158, 101, - 102, 103, 0, 104, 357, 0, 0, 84, 27, 0, - 0, 0, 0, 145, 4, 5, 344, 6, 7, 8, - 0, 345, 146, 0, 0, 147, 346, 9, 10, 347, - 348, 0, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 349, 0, 23, 24, 25, 26, - 0, 0, 0, 148, 28, 350, 0, 29, 30, 351, - 149, 31, 0, 32, 284, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 151, - 0, 0, 352, 0, 0, 47, 0, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 0, 0, 0, 152, 62, 0, 0, 153, 154, - 0, 63, 285, 0, 353, 0, 0, 414, 0, 0, - 0, 155, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 355, 0, 156, 0, 82, 0, 0, 356, 83, 85, - 86, 157, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 158, 101, 102, 103, - 0, 104, 357, 0, 0, 84, 27, 0, 0, 0, - 0, + -25, 332, 446, 246, 339, 306, 450, 319, 428, 251, + 429, 317, 331, 376, 144, 377, 461, 437, 443, 266, + 378, 316, 421, 385, 314, 170, 407, 445, 431, 304, + 381, 251, 244, -24, 334, 199, 191, 217, 380, -19, + 246, 384, -24, 412, 397, 139, 399, 403, 139, 404, + 459, 244, 171, 373, 243, 171, 174, 331, 462, 239, + 342, 175, 191, 139, 460, 217, 139, 269, 264, -25, + 191, 194, 139, 139, 227, 139, 375, 139, 455, 181, + 139, 453, 139, 438, 142, 227, 227, 2, 1, 207, + 254, 139, 207, 227, 200, 219, 424, 200, 341, 435, + 179, 176, 139, 207, 227, 240, 219, 248, 143, 228, + 167, 307, 0, 249, 0, 439, 210, 321, 0, 322, + 228, 228, 0, 29, 320, 0, 0, 182, 228, 0, + 222, 0, 0, 0, 0, 456, 0, 0, 0, 228, + 222, 210, 0, 308, 210, 309, 220, 211, 180, 212, + 256, 0, 0, 48, 223, 0, 342, 220, 168, 321, + 224, 322, 222, 454, 223, 323, 61, 257, 0, 383, + 224, 409, 211, 208, 212, 211, 208, 212, 423, 0, + 0, 0, 320, 258, 0, 0, 223, 208, 433, 225, + 0, 0, 224, 0, -124, 235, 420, 177, 140, 225, + 270, 241, 271, -124, 0, 259, -124, 323, 0, 0, + 204, 0, 0, 201, 145, 436, 169, 321, 0, 322, + 0, 225, 272, 146, -124, 0, 147, 0, 0, 0, + 0, 0, 0, -124, -124, 0, -124, 0, 0, 0, + 0, -124, 273, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 148, 0, 0, 0, 0, 0, + 0, 149, 0, 0, -124, 323, 0, 0, 0, 301, + 0, -124, 274, 0, 0, 0, 0, -91, 0, 0, + 0, 0, 0, 0, 0, -124, 0, 0, 0, -124, + -124, 0, 275, 276, 0, 0, 0, 277, 0, 0, + 0, 0, -124, 0, 0, 152, 0, 278, 0, 153, + 154, 0, 0, 0, 0, -124, 0, 0, 0, -124, + -124, 0, 155, -124, 0, 0, 0, 0, 0, 0, + 0, 0, -124, 0, 0, 0, 0, 279, 0, 0, + 0, 0, 0, 156, 0, 0, 0, -124, 0, 0, + 0, 0, 157, -124, 0, 0, 145, 0, 0, 0, + 0, 0, -124, 0, 280, 146, 0, 158, 147, 0, + 0, 0, 0, 0, 0, 0, 0, -124, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 149, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 153, 154, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 155, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 6, 7, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 0, 23, 24, 25, 26, 0, + 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 0, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 0, + 0, 0, 0, 82, 0, 0, 0, 0, 85, 86, + 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 6, 7, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, + 0, 23, 24, 25, 26, 0, 0, 0, 0, 28, + 0, 0, 29, 0, 0, 0, 0, 0, 32, 0, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 0, 0, 0, 0, 82, + 0, 0, 0, 0, 85, 86, 0, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 104, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 0, 6, 7, + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 23, 24, 25, + 26, 0, 0, 0, 0, 28, 0, 0, 29, 260, + 0, 0, 0, 0, 32, 0, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 0, 0, 0, 0, 82, 0, 0, 0, 0, + 85, 86, 0, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 0, 6, 7, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 0, 0, 23, 24, 25, 26, 0, 0, 0, + 0, 28, 0, 0, 29, 448, 0, 0, 0, 0, + 32, 0, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 449, 0, 0, + 0, 82, 0, 0, 0, 0, 85, 86, 0, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, + 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, + 0, 9, 10, 0, 0, 0, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, + 23, 24, 25, 26, 0, 0, 0, 0, 28, 0, + 0, 29, 30, 0, 0, 31, 0, 32, 0, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 0, 0, 0, 0, 0, 0, 47, + 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 0, 0, 0, 0, 62, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 0, 0, 0, 0, 82, 0, + 0, 0, 83, 85, 86, 0, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 104, 0, 0, 0, 84, + 27, 0, 0, 0, 0, 4, 5, 0, 6, 7, + 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, + 0, 0, 0, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 23, 24, 25, + 26, 0, 0, 0, 0, 28, 0, 0, 29, 30, + 0, 0, 31, 0, 32, 0, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 0, 0, 0, 0, 0, 0, 47, 0, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 0, 0, 0, 0, 62, 0, 0, 0, + 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 0, 0, 0, 0, 82, 0, 0, 0, 83, + 85, 86, 0, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 237, 0, 0, 0, 84, 27, 0, 0, + 0, 0, 4, 5, 0, 6, 7, 8, 0, 0, + 0, 0, 0, 0, 0, 9, 10, 0, 0, 0, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 0, 0, 23, 24, 25, 26, 0, 0, + 0, 0, 28, 0, 0, 29, 30, 0, 0, 31, + 0, 32, 0, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, + 0, 0, 0, 47, 0, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, + 0, 0, 0, 62, 0, 0, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 0, 0, + 0, 0, 82, 0, 0, 0, 83, 85, 86, 0, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 0, 101, 102, 103, 0, 104, + 0, 0, 0, 84, 27, 0, 0, 0, 0, 4, + 5, 0, 6, 7, 8, 0, 0, 0, 0, 0, + 0, 0, 9, 10, 0, 0, 0, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, + 0, 23, 24, 25, 26, 0, 0, 0, 0, 28, + 0, 0, 29, 30, 0, 0, 31, 0, 32, 0, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, + 47, 0, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, + 62, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 457, 0, 0, 0, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 0, 0, 0, 0, 82, + 0, 0, 0, 83, 85, 86, 0, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 104, 0, 0, 0, + 84, 27, 0, 0, 0, 0, 4, 5, 0, 6, + 7, 8, 0, 0, 0, 0, 0, 0, 0, 9, + 10, 0, 0, 0, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 0, 0, 23, 24, + 25, 26, 0, 0, 0, 0, 28, 0, 0, 29, + 30, 0, 0, 31, 0, 32, 0, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 0, 0, 0, 0, 0, 0, 47, 0, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 0, 0, 0, 0, 62, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, + 441, 0, 0, 0, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 0, 0, 0, 0, 82, 0, 0, 0, + 83, 85, 86, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, + 102, 103, 0, 104, 0, 0, 0, 84, 27, 0, + 0, 0, 0, 4, 5, 0, 6, 7, 8, 0, + 0, 0, 0, 0, 0, 0, 9, 10, 0, 0, + 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 0, 23, 24, 25, 26, 0, + 0, 0, 0, 28, 0, 0, 29, 30, 0, 0, + 31, 0, 32, 0, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, + 0, 0, 0, 0, 47, 0, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 0, 0, 0, 312, 0, 0, + 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 0, + 0, 0, 0, 82, 0, 0, 0, 83, 85, 86, + 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 104, 0, 0, 0, 84, 27, 0, 0, 0, 0, + 4, 5, 0, 6, 7, 8, 0, 0, 0, 0, + 0, 0, 0, 9, 10, 0, 0, 0, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 0, 0, 23, 24, 25, 26, 0, 0, 0, 0, + 28, 0, 0, 29, 30, 0, 0, 31, 0, 32, + 0, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, + 0, 47, 0, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, + 0, 62, 0, 0, 0, 0, 0, 63, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 418, 0, 0, 0, + 82, 0, 0, 0, 83, 85, 86, 0, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 0, 101, 102, 103, 0, 104, 0, 0, + 0, 84, 27, 0, 0, 0, 0, 4, 5, 0, + 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, + 9, 10, 0, 0, 0, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 0, 0, 23, + 24, 25, 26, 0, 0, 0, 0, 28, 0, 0, + 29, 30, 0, 0, 31, 0, 32, 0, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 0, 0, 0, 0, 0, 0, 47, 0, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 0, 0, 0, 0, 62, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, + 0, 267, 0, 0, 0, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 0, 0, 0, 0, 82, 0, 0, + 0, 83, 85, 86, 0, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 104, 0, 0, 0, 84, 27, + 0, 0, 0, 0, 145, 0, 5, 0, 6, 7, + 8, 0, 0, 146, 0, 0, 147, 0, 0, 0, + 0, 0, 0, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 23, 24, 25, + 26, 0, 0, 0, 148, 28, 0, 0, 29, 0, + 0, 149, 0, 0, 32, 150, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 151, 0, 0, 0, 0, 0, 0, 0, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 0, 0, 0, 152, 0, 0, 0, 153, + 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 155, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 0, 0, 156, 0, 82, 0, 0, 0, 0, + 85, 86, 157, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 158, 101, 102, + 103, 0, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 145, 0, 5, 0, 6, 7, 8, 0, + 0, 146, 0, 0, 147, 0, 0, 0, 0, 0, + 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 0, 23, 24, 25, 26, 0, + 0, 0, 148, 28, 0, 0, 29, 0, 0, 149, + 0, 0, 32, 150, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 151, 0, + 0, 0, 0, 0, 0, 0, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 0, 0, 0, 152, 0, 0, 0, 153, 154, 0, + 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, + 155, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 0, + 0, 156, 0, 82, 0, 0, 0, 0, 85, 86, + 157, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 158, 101, 102, 103, 0, + 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 145, 0, 5, 0, 6, 7, 8, 0, 0, 146, + 0, 0, 147, 0, 0, 0, 0, 0, 0, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 0, 0, 23, 24, 25, 26, 0, 0, 0, + 148, 28, 0, 0, 29, 0, 0, 149, 0, 0, + 32, 150, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 151, 0, 0, 0, + 0, 0, 0, 0, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, + 0, 152, 0, 0, 0, 153, 154, 0, 0, 0, + 0, 0, 0, 0, 452, 0, 0, 0, 155, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 0, 0, 156, + 0, 82, 0, 0, 0, 0, 85, 86, 157, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 158, 101, 102, 103, 0, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, + 5, 0, 6, 7, 8, 0, 0, 146, 0, 0, + 147, 0, 0, 0, 0, 0, 0, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, + 0, 23, 24, 25, 26, 0, 0, 0, 148, 28, + 0, 0, 29, 0, 0, 149, 0, 0, 32, 150, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 151, 0, 0, 0, 0, 0, + 0, 0, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 0, 0, 0, 152, + 0, 0, 0, 153, 154, 0, 0, 0, 0, 0, + 0, 0, 206, 0, 0, 0, 155, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 0, 0, 156, 0, 82, + 0, 0, 0, 0, 85, 86, 157, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 158, 101, 102, 103, 0, 104, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 145, 0, 5, 0, + 6, 7, 8, 0, 0, 146, 0, 0, 147, 0, + 0, 0, 0, 0, 0, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 0, 0, 23, + 24, 25, 26, 0, 0, 0, 148, 28, 0, 0, + 29, 0, 0, 149, 0, 0, 32, 284, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 151, 0, 0, 0, 0, 0, 0, 0, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 0, 0, 0, 152, 0, 0, + 0, 153, 154, 0, 0, 285, 0, 0, 0, 0, + 0, 0, 0, 0, 155, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 286, 0, 156, 0, 82, 0, 0, + 0, 0, 85, 86, 157, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 158, + 101, 102, 103, 0, 104, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 145, 4, 5, 0, 6, 7, + 8, 0, 0, 146, 0, 0, 147, 0, 9, 10, + 0, 0, 0, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 23, 24, 25, + 26, 0, 0, 0, 148, 28, 0, 0, 29, 30, + 0, 149, 31, 0, 32, 150, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 151, 0, 0, 0, 0, 0, 47, 0, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 0, 0, 0, 152, 62, 0, 0, 153, + 154, 0, 63, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 155, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 0, 0, 156, 0, 82, 0, 0, 0, 83, + 85, 86, 157, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 158, 101, 102, + 103, 0, 104, 0, 0, 0, 84, 27, 0, 0, + 0, 0, 145, 4, 5, 0, 6, 7, 8, 0, + 0, 146, 0, 0, 147, 0, 9, 10, 0, 0, + 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 0, 23, 24, 25, 26, 0, + 0, 0, 148, 28, 0, 0, 29, 30, 0, 149, + 31, 0, 32, 284, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 151, 0, + 0, 0, 0, 0, 47, 0, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 0, 0, 0, 152, 62, 0, 0, 153, 154, 0, + 63, 285, 0, 0, 0, 0, 0, 0, 0, 0, + 155, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 355, + 0, 156, 0, 82, 0, 0, 0, 83, 85, 86, + 157, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 158, 101, 102, 103, 0, + 104, 0, 0, 0, 84, 27, 0, 0, 0, 0, + 145, 4, 5, 344, 6, 7, 8, 0, 345, 146, + 0, 0, 147, 346, 9, 10, 347, 348, 0, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 349, 0, 23, 24, 25, 26, 0, 0, 0, + 148, 28, 350, 0, 29, 30, 351, 149, 31, 0, + 32, 284, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 151, 0, 0, 341, + 0, 0, 47, 0, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, + 0, 152, 62, 0, 0, 153, 154, 0, 63, 285, + 0, 353, 0, 0, 0, 0, 0, 0, 155, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 355, 0, 156, + 0, 82, 0, 0, 356, 83, 85, 86, 157, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 158, 101, 102, 103, 0, 104, 357, + 0, 0, 84, 27, 0, 0, 0, 0, 145, 4, + 5, 344, 6, 7, 8, 0, 345, 146, 0, 0, + 147, 346, 9, 10, 347, 348, 0, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 349, + 0, 23, 24, 25, 26, 0, 0, 0, 148, 28, + 350, 0, 29, 30, 351, 149, 31, 0, 32, 284, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 151, 0, 0, 352, 0, 0, + 47, 0, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 0, 0, 0, 152, + 62, 0, 0, 153, 154, 0, 63, 285, 0, 353, + 0, 0, 0, 0, 0, 0, 155, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 355, 0, 156, 0, 82, + 0, 0, 356, 83, 85, 86, 157, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 158, 101, 102, 103, 0, 104, 357, 0, 0, + 84, 27, 0, 0, 0, 0, 145, 4, 5, 344, + 6, 7, 8, 0, 345, 146, 0, 0, 147, 346, + 9, 10, 347, 348, 0, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 349, 0, 23, + 24, 25, 26, 0, 0, 0, 148, 28, 350, 0, + 29, 30, 351, 149, 31, 0, 32, 284, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 151, 0, 0, 352, 0, 0, 47, 0, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 0, 0, 0, 152, 62, 0, + 0, 153, 154, 0, 63, 285, 0, 353, 0, 0, + 434, 0, 0, 0, 155, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 355, 0, 156, 0, 82, 0, 0, + 356, 83, 85, 86, 157, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 158, + 101, 102, 103, 0, 104, 357, 0, 0, 84, 27, + 0, 0, 0, 0, 145, 4, 5, 344, 6, 7, + 8, 0, 345, 146, 0, 0, 147, 346, 9, 10, + 347, 348, 0, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 349, 0, 23, 24, 25, + 26, 0, 0, 0, 148, 28, 350, 0, 29, 30, + 351, 149, 31, 0, 32, 284, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 151, 0, 0, 352, 0, 0, 47, 0, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 0, 0, 0, 152, 62, 0, 0, 153, + 154, 0, 63, 285, 0, 353, 0, 0, 416, 0, + 0, 0, 155, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 355, 0, 156, 0, 82, 0, 0, 356, 83, + 85, 86, 157, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 158, 101, 102, + 103, 0, 104, 357, 0, 0, 84, 27, 0, 0, + 0, 0, 145, 4, 5, 344, 6, 7, 8, 0, + 345, 146, 0, 0, 147, 346, 9, 10, 347, 348, + 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 349, 0, 23, 24, 25, 26, 0, + 0, 0, 148, 28, 350, 0, 29, 30, 351, 149, + 31, 0, 32, 284, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 151, 0, + 0, 352, 0, 0, 47, 0, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 0, 0, 0, 152, 62, 0, 0, 153, 154, 0, + 63, 285, 0, 353, 0, 0, 354, 0, 0, 0, + 155, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 355, + 0, 156, 0, 82, 0, 0, 356, 83, 85, 86, + 157, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 158, 101, 102, 103, 0, + 104, 357, 0, 0, 84, 27, 0, 0, 0, 0, + 145, 4, 5, 344, 6, 7, 8, 0, 345, 146, + 0, 0, 147, 346, 9, 10, 347, 348, 0, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 349, 0, 23, 24, 25, 26, 0, 0, 0, + 148, 28, 350, 0, 29, 30, 351, 149, 31, 0, + 32, 284, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 151, 0, 0, 352, + 0, 0, 47, 0, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, + 0, 152, 62, 0, 0, 153, 154, 0, 63, 285, + 0, 353, 0, 0, 414, 0, 0, 0, 155, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 355, 0, 156, + 0, 82, 0, 0, 356, 83, 85, 86, 157, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 158, 101, 102, 103, 0, 104, 357, + 0, 0, 84, 27, 0, 0, 0, 0, - 406, 138, 242, 190, 186, 398, 215, 213, 408, 178, - 193, 137, 202, 422, 214, 136, 310, 419, 335, 261, - 183, 283, 262, 374, 340, 282, 372, 302, 255, 330, - 382, 406, 303, 141, 238, 343, 253, 187, 265, 198, - 310, 198, 310, 310, 310, 218, 221, 0, 0, 198, - 198, 198, 310, 216, 198, 234, 209, 372, 310, 198, - 198, 372, 196, 229, 198, 198, 372, 230, 372, 252, - 372, 111, 0, 198, 166, 372, 250, 447, 372, 315, - 318, 440, 247, 0, 0, 0, 198, 198, 184, 444, - 226, 233, 185, 198, 198, 405, 165, 231, 198, 198, - 166, 236, 198, 232, 389, 417, 245, 372, 0, 413, - 166, 0, 198, 300, 417, 196, 411, 313, 166, 372, - 401, 198, 165, 417, 198, 196, 379, 458, 166, 338, - 287, 295, 165, 198, 196, 0, 268, 196, 393, 333, - 165, 451, 0, 0, 189, 166, 196, 0, 442, 389, - 165, 386, 425, 372, 189, 387, 0, 401, 336, 393, - 0, 337, 0, 0, 0, 432, 0, 165, 164, 0, - 389, 396, 189, 0, 0, 0, 426, 395, 0, 0, - 0, 0, 392, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 396, 0, 0, 0, 0, 0, 395, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, - 0, 430, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 287, 295, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 305, 0, 0}; + 242, 406, 398, 422, 408, 178, 137, 190, 186, 215, + 214, 213, 136, 193, 111, 202, 183, 141, 282, 374, + 419, 372, 340, 302, 283, 262, 261, 335, 330, 382, + 253, 310, 238, 303, 187, 343, 255, 406, 265, 372, + 310, 0, 0, 310, 198, 198, 209, 216, 310, 310, + 198, 310, 0, 198, 0, 198, 198, 198, 198, 218, + 221, 234, 226, 196, 198, 245, 198, 198, 372, 310, + 166, 0, 184, 138, 252, 247, 185, 447, 250, 372, + 444, 198, 198, 372, 230, 440, 318, 417, 315, 236, + 372, 372, 165, 198, 198, 198, 198, 231, 229, 198, + 233, 372, 372, 232, 300, 389, 405, 196, 338, 313, + 166, 166, 0, 198, 372, 0, 0, 0, 401, 166, + 0, 287, 295, 166, 166, 0, 196, 417, 458, 198, + 0, 411, 165, 165, 451, 425, 198, 336, 417, 379, + 337, 165, 196, 300, 268, 165, 165, 164, 0, 196, + 0, 333, 386, 198, 189, 372, 387, 0, 415, 426, + 287, 295, 393, 189, 401, 0, 196, 189, 442, 0, + 0, 0, 432, 389, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 396, 0, 0, 0, 0, + 0, 395, 0, 413, 0, 0, 392, 0, 0, 0, + 0, 305, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 389, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 396, + 0, 0, 0, 0, 0, 395, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 430, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; const short GLSLParserTable::action_check [] = { - 111, 79, 112, 134, 45, 79, 164, 76, 76, 134, - 134, 168, 79, 45, 79, 112, 52, 134, 76, 52, - 77, 45, 134, 112, 0, 134, 18, 79, 45, 17, - 114, 77, 45, 52, 18, 114, 52, 18, 134, 4, - 79, 112, 79, 44, 134, 166, 112, 52, 164, 112, - 114, 14, 79, 168, 77, 52, 52, 4, 112, 52, - 45, 114, 52, 114, 79, 79, 18, 79, 99, 14, - 18, 45, 134, 52, 18, 17, 18, 18, 18, 77, - 18, 18, 52, 78, 18, 21, 54, 76, 18, 18, - 101, 17, 18, 54, 21, 78, 107, 1, 2, 52, - 78, 18, 18, 77, 18, 78, 21, 46, 54, 78, - 56, 46, -1, -1, -1, -1, 22, 104, 113, -1, - 45, -1, 104, 76, -1, -1, -1, -1, -1, 51, - 113, 54, 104, 39, 102, 113, 134, -1, -1, -1, - 113, 102, -1, 50, 113, 134, -1, 19, 135, 55, - 137, 50, 77, 135, 79, 137, 102, -1, 97, 81, - 6, -1, 97, 135, 134, 137, 19, 74, 50, 105, - 114, 77, 94, 80, 114, 74, -1, 114, 105, 102, - 114, 80, 54, -1, 56, 114, 3, -1, 5, -1, - 105, -1, 74, 134, -1, -1, 134, 114, 80, -1, - -1, 54, 109, 56, 134, 7, -1, 7, 25, -1, - 109, -1, -1, -1, 16, -1, 16, 7, 134, 19, - 134, -1, -1, -1, -1, -1, 16, 109, 45, 19, - 102, -1, -1, -1, -1, -1, -1, 160, -1, -1, - -1, -1, -1, -1, -1, 47, -1, 47, -1, 102, - -1, -1, 54, -1, 54, -1, -1, 47, 75, -1, - -1, 114, 52, -1, 54, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 95, 96, - -1, -1, -1, 100, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 110, -1, -1, 98, -1, 98, -1, - 102, 103, 102, 103, -1, -1, -1, -1, 98, -1, - -1, -1, 102, 103, -1, 115, -1, -1, -1, -1, - -1, -1, -1, 140, -1, 115, -1, -1, -1, 7, - -1, -1, -1, -1, 136, -1, 136, -1, 16, -1, - -1, 19, -1, 145, -1, 145, 136, -1, -1, -1, - 167, -1, -1, -1, -1, 145, -1, -1, 160, -1, - 160, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 160, -1, -1, -1, -1, -1, 54, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 102, 103, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 115, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 145, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 160, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 9, -1, 11, - 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, -1, -1, 40, 41, - 42, 43, -1, -1, -1, -1, 48, -1, -1, -1, - -1, -1, -1, -1, -1, 57, -1, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, -1, -1, -1, 138, -1, -1, -1, - -1, 143, 144, -1, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, -1, 161, - 162, 163, -1, 165, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 9, -1, 11, 12, 13, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, -1, -1, 40, 41, 42, 43, -1, -1, - -1, -1, 48, -1, -1, 51, -1, -1, -1, -1, - -1, 57, -1, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, -1, -1, -1, - -1, -1, -1, -1, -1, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, -1, -1, - -1, -1, 138, -1, -1, -1, -1, 143, 144, -1, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, -1, 161, 162, 163, -1, 165, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, - -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, - 40, 41, 42, 43, -1, -1, -1, -1, 48, -1, - -1, 51, 52, -1, -1, -1, -1, 57, -1, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, -1, -1, -1, -1, -1, -1, -1, - -1, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, -1, -1, -1, 138, -1, - -1, -1, -1, 143, 144, -1, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - -1, 161, 162, 163, -1, 165, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 9, -1, 11, 12, 13, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, -1, -1, 40, 41, 42, 43, - -1, -1, -1, -1, 48, -1, -1, 51, 52, -1, - -1, -1, -1, 57, -1, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, -1, - -1, -1, -1, -1, -1, -1, -1, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, -1, -1, -1, 138, -1, -1, -1, -1, 143, - 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, -1, 161, 162, 163, - -1, 165, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 8, 9, -1, 11, 12, 13, -1, -1, -1, - -1, -1, -1, -1, 21, 22, -1, -1, -1, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, -1, -1, 40, 41, 42, 43, -1, -1, -1, - -1, 48, -1, -1, 51, 52, -1, -1, 55, -1, - 57, -1, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, -1, -1, -1, -1, - -1, -1, 79, -1, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, -1, -1, - -1, -1, 99, -1, -1, -1, -1, -1, 105, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, -1, -1, -1, - -1, 138, -1, -1, -1, 142, 143, 144, -1, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, -1, 161, 162, 163, -1, 165, -1, - -1, -1, 169, 170, -1, -1, -1, -1, 8, 9, - -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, - -1, 21, 22, -1, -1, -1, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, - 40, 41, 42, 43, -1, -1, -1, -1, 48, -1, - -1, 51, 52, -1, -1, 55, -1, 57, -1, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, -1, -1, -1, -1, -1, -1, 79, - -1, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, -1, -1, -1, -1, 99, - -1, -1, -1, -1, -1, 105, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, -1, -1, -1, 138, -1, - -1, -1, 142, 143, 144, -1, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - -1, 161, 162, 163, -1, 165, -1, -1, -1, 169, - 170, -1, -1, -1, -1, 8, 9, -1, 11, 12, - 13, -1, -1, -1, -1, -1, -1, -1, 21, 22, - -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, -1, -1, 40, 41, 42, - 43, -1, -1, -1, -1, 48, -1, -1, 51, 52, - -1, -1, 55, -1, 57, -1, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - -1, -1, -1, -1, -1, -1, 79, -1, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, -1, -1, -1, -1, 99, -1, -1, -1, - -1, -1, 105, -1, -1, -1, -1, -1, -1, 112, - -1, -1, -1, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, -1, -1, -1, -1, 138, -1, -1, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, -1, 161, 162, - 163, -1, 165, -1, -1, -1, 169, 170, -1, -1, - -1, -1, 8, 9, -1, 11, 12, 13, -1, -1, - -1, -1, -1, -1, -1, 21, 22, -1, -1, -1, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, -1, -1, 40, 41, 42, 43, -1, -1, - -1, -1, 48, -1, -1, 51, 52, -1, -1, 55, - -1, 57, -1, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, -1, -1, -1, - -1, -1, -1, 79, -1, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, -1, - -1, -1, -1, 99, -1, -1, -1, -1, -1, 105, - -1, -1, -1, -1, -1, -1, 112, -1, -1, -1, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, -1, -1, - -1, -1, 138, -1, -1, -1, 142, 143, 144, -1, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, -1, 161, 162, 163, -1, 165, - -1, -1, -1, 169, 170, -1, -1, -1, -1, 8, - 9, -1, 11, 12, 13, -1, -1, -1, -1, -1, - -1, -1, 21, 22, -1, -1, -1, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, - -1, 40, 41, 42, 43, -1, -1, -1, -1, 48, - -1, -1, 51, 52, -1, -1, 55, -1, 57, -1, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, -1, -1, -1, -1, -1, -1, - 79, -1, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, -1, -1, -1, -1, - 99, -1, -1, -1, -1, -1, 105, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, -1, -1, -1, 138, - -1, -1, -1, 142, 143, 144, -1, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, -1, 161, 162, 163, -1, 165, -1, -1, -1, - 169, 170, -1, -1, -1, -1, 8, 9, -1, 11, - 12, 13, -1, -1, -1, -1, -1, -1, -1, 21, - 22, -1, -1, -1, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, -1, -1, 40, 41, - 42, 43, -1, -1, -1, -1, 48, -1, -1, 51, - 52, -1, -1, 55, -1, 57, -1, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, -1, -1, -1, -1, -1, -1, 79, -1, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, -1, -1, -1, -1, 99, -1, -1, - -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, - 112, -1, -1, -1, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, -1, -1, -1, 138, -1, -1, -1, - 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, -1, 161, - 162, 163, -1, 165, -1, -1, -1, 169, 170, -1, - -1, -1, -1, 8, 9, -1, 11, 12, 13, -1, - -1, -1, -1, -1, -1, -1, 21, 22, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, -1, -1, 40, 41, 42, 43, -1, - -1, -1, -1, 48, -1, -1, 51, 52, -1, -1, - 55, -1, 57, -1, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, -1, -1, - -1, -1, -1, -1, 79, -1, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - -1, -1, -1, -1, 99, -1, -1, -1, -1, -1, - 105, -1, -1, -1, -1, -1, -1, 112, -1, -1, - -1, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, - -1, -1, -1, 138, -1, -1, -1, 142, 143, 144, - -1, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, -1, 161, 162, 163, -1, - 165, -1, -1, -1, 169, 170, -1, -1, -1, -1, - 8, 9, -1, 11, 12, 13, -1, -1, -1, -1, - -1, -1, -1, 21, 22, -1, -1, -1, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - -1, -1, 40, 41, 42, 43, -1, -1, -1, -1, - 48, -1, -1, 51, 52, -1, -1, 55, -1, 57, - -1, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, -1, -1, -1, -1, -1, - -1, 79, -1, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, -1, -1, -1, - -1, 99, -1, -1, -1, -1, -1, 105, -1, -1, - -1, -1, -1, -1, 112, -1, -1, -1, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, -1, -1, -1, -1, - 138, -1, -1, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, -1, 161, 162, 163, -1, 165, -1, -1, - -1, 169, 170, -1, -1, -1, -1, 7, -1, 9, - -1, 11, 12, 13, -1, -1, 16, -1, -1, 19, - -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, - 40, 41, 42, 43, -1, -1, -1, 47, 48, -1, - -1, 51, -1, -1, 54, -1, -1, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, - -1, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, -1, -1, -1, 98, -1, - -1, -1, 102, 103, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, -1, 136, -1, 138, -1, - -1, -1, -1, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, -1, 165, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 7, -1, 9, -1, 11, - 12, 13, -1, -1, 16, -1, -1, 19, -1, -1, - -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, -1, -1, 40, 41, - 42, 43, -1, -1, -1, 47, 48, -1, -1, 51, - -1, -1, 54, -1, -1, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, -1, -1, -1, -1, -1, -1, -1, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, -1, -1, -1, 98, -1, -1, -1, - 102, 103, -1, -1, -1, -1, -1, -1, -1, 111, - -1, -1, -1, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, -1, 136, -1, 138, -1, -1, -1, - -1, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, -1, 165, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 7, -1, 9, -1, 11, 12, 13, - -1, -1, 16, -1, -1, 19, -1, -1, -1, -1, - -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, -1, -1, 40, 41, 42, 43, - -1, -1, -1, 47, 48, -1, -1, 51, -1, -1, - 54, -1, -1, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - -1, -1, -1, -1, -1, -1, -1, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, -1, -1, -1, 98, -1, -1, -1, 102, 103, - -1, -1, -1, -1, -1, -1, -1, 111, -1, -1, - -1, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - -1, -1, 136, -1, 138, -1, -1, -1, -1, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - -1, 165, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 7, -1, 9, -1, 11, 12, 13, -1, -1, - 16, -1, -1, 19, -1, -1, -1, -1, -1, -1, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, -1, -1, 40, 41, 42, 43, -1, -1, - -1, 47, 48, -1, -1, 51, -1, -1, 54, -1, - -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, - -1, -1, -1, -1, -1, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, -1, - -1, -1, 98, -1, -1, -1, 102, 103, -1, -1, - -1, -1, -1, -1, -1, 111, -1, -1, -1, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, -1, -1, - 136, -1, 138, -1, -1, -1, -1, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, -1, 165, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, - -1, 9, -1, 11, 12, 13, -1, -1, 16, -1, - -1, 19, -1, -1, -1, -1, -1, -1, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - -1, -1, 40, 41, 42, 43, -1, -1, -1, 47, - 48, -1, -1, 51, -1, -1, 54, -1, -1, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, - -1, -1, -1, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, -1, -1, -1, - 98, -1, -1, -1, 102, 103, -1, -1, 106, -1, - -1, -1, -1, -1, -1, -1, -1, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, -1, 136, -1, - 138, -1, -1, -1, -1, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, -1, 165, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 7, 8, 9, - -1, 11, 12, 13, -1, -1, 16, -1, -1, 19, - -1, 21, 22, -1, -1, -1, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, - 40, 41, 42, 43, -1, -1, -1, 47, 48, -1, - -1, 51, 52, -1, 54, 55, -1, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, -1, -1, -1, -1, -1, 79, - -1, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, -1, -1, -1, 98, 99, - -1, -1, 102, 103, -1, 105, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, -1, 136, -1, 138, -1, - -1, -1, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, -1, 165, -1, -1, -1, 169, - 170, -1, -1, -1, -1, 7, 8, 9, -1, 11, - 12, 13, -1, -1, 16, -1, -1, 19, -1, 21, - 22, -1, -1, -1, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, -1, -1, 40, 41, - 42, 43, -1, -1, -1, 47, 48, -1, -1, 51, - 52, -1, 54, 55, -1, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, -1, -1, -1, -1, -1, 79, -1, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, -1, -1, -1, 98, 99, -1, -1, - 102, 103, -1, 105, 106, -1, -1, -1, -1, -1, - -1, -1, -1, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, -1, 136, -1, 138, -1, -1, -1, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, -1, 165, -1, -1, -1, 169, 170, -1, - -1, -1, -1, 7, 8, 9, 10, 11, 12, 13, - -1, 15, 16, -1, -1, 19, 20, 21, 22, 23, - 24, -1, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, -1, 40, 41, 42, 43, - -1, -1, -1, 47, 48, 49, -1, 51, 52, 53, - 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - -1, -1, 76, -1, -1, 79, -1, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, -1, -1, -1, 98, 99, -1, -1, 102, 103, - -1, 105, 106, -1, 108, -1, -1, -1, -1, -1, - -1, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, -1, 136, -1, 138, -1, -1, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - -1, 165, 166, -1, -1, 169, 170, -1, -1, -1, - -1, 7, 8, 9, 10, 11, 12, 13, -1, 15, - 16, -1, -1, 19, 20, 21, 22, 23, 24, -1, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, -1, 40, 41, 42, 43, -1, -1, - -1, 47, 48, 49, -1, 51, 52, 53, 54, 55, - -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, - 76, -1, -1, 79, -1, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, -1, - -1, -1, 98, 99, -1, -1, 102, 103, -1, 105, - 106, -1, 108, -1, -1, -1, -1, -1, -1, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, -1, - 136, -1, 138, -1, -1, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, -1, 165, - 166, -1, -1, 169, 170, -1, -1, -1, -1, 7, - 8, 9, 10, 11, 12, 13, -1, 15, 16, -1, - -1, 19, 20, 21, 22, 23, 24, -1, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, -1, 40, 41, 42, 43, -1, -1, -1, 47, - 48, 49, -1, 51, 52, 53, 54, 55, -1, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, -1, -1, 76, -1, - -1, 79, -1, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, -1, -1, -1, - 98, 99, -1, -1, 102, 103, -1, 105, 106, -1, - 108, -1, -1, 111, -1, -1, -1, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, -1, 136, -1, - 138, -1, -1, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, -1, 165, 166, -1, - -1, 169, 170, -1, -1, -1, -1, 7, 8, 9, - 10, 11, 12, 13, -1, 15, 16, -1, -1, 19, - 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, - 40, 41, 42, 43, -1, -1, -1, 47, 48, 49, - -1, 51, 52, 53, 54, 55, -1, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, -1, -1, 76, -1, -1, 79, - -1, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, -1, -1, -1, 98, 99, - -1, -1, 102, 103, -1, 105, 106, -1, 108, -1, - -1, 111, -1, -1, -1, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, -1, 136, -1, 138, -1, - -1, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, -1, 165, 166, -1, -1, 169, - 170, -1, -1, -1, -1, 7, 8, 9, 10, 11, - 12, 13, -1, 15, 16, -1, -1, 19, 20, 21, - 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, -1, 40, 41, - 42, 43, -1, -1, -1, 47, 48, 49, -1, 51, - 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, -1, -1, 76, -1, -1, 79, -1, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, -1, -1, -1, 98, 99, -1, -1, - 102, 103, -1, 105, 106, -1, 108, -1, -1, 111, - -1, -1, -1, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, -1, 136, -1, 138, -1, -1, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, -1, 165, 166, -1, -1, 169, 170, -1, - -1, -1, -1, 7, 8, 9, 10, 11, 12, 13, - -1, 15, 16, -1, -1, 19, 20, 21, 22, 23, - 24, -1, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, -1, 40, 41, 42, 43, - -1, -1, -1, 47, 48, 49, -1, 51, 52, 53, - 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - -1, -1, 76, -1, -1, 79, -1, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, -1, -1, -1, 98, 99, -1, -1, 102, 103, - -1, 105, 106, -1, 108, -1, -1, 111, -1, -1, - -1, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, -1, 136, -1, 138, -1, -1, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - -1, 165, 166, -1, -1, 169, 170, -1, -1, -1, - -1, + 79, 77, 45, 6, 18, 52, 76, 114, 111, 168, + 79, 45, 52, 134, 76, 17, 134, 52, 45, 77, + 134, 112, 79, 79, 45, 79, 79, 112, 114, 134, + 79, 168, 164, 79, 112, 112, 52, 4, 166, 114, + 6, 134, 79, 44, 134, 18, 114, 52, 18, 45, + 134, 164, 52, 134, 79, 52, 45, 52, 0, 114, + 134, 99, 52, 18, 112, 4, 18, 112, 112, 79, + 52, 77, 18, 18, 78, 18, 17, 18, 77, 54, + 18, 52, 18, 45, 52, 78, 78, 1, 2, 21, + 17, 18, 21, 78, 18, 46, 76, 18, 76, 18, + 54, 18, 18, 21, 78, 18, 46, 101, 76, 113, + 54, 45, -1, 107, -1, 77, 104, 54, -1, 56, + 113, 113, -1, 51, 19, -1, -1, 102, 113, -1, + 50, -1, -1, -1, -1, 134, -1, -1, -1, 113, + 50, 104, -1, 77, 104, 79, 97, 135, 102, 137, + 22, -1, -1, 81, 74, -1, 134, 97, 102, 54, + 80, 56, 50, 134, 74, 102, 94, 39, -1, 114, + 80, 114, 135, 105, 137, 135, 105, 137, 114, -1, + -1, -1, 19, 55, -1, -1, 74, 105, 134, 109, + -1, -1, 80, -1, 7, 14, 134, 114, 114, 109, + 3, 114, 5, 16, -1, 77, 19, 102, -1, -1, + 134, -1, -1, 134, 7, 134, 160, 54, -1, 56, + -1, 109, 25, 16, 7, -1, 19, -1, -1, -1, + -1, -1, -1, 16, 47, -1, 19, -1, -1, -1, + -1, 54, 45, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 47, -1, -1, -1, -1, -1, + -1, 54, -1, -1, 47, 102, -1, -1, -1, 52, + -1, 54, 75, -1, -1, -1, -1, 114, -1, -1, + -1, -1, -1, -1, -1, 98, -1, -1, -1, 102, + 103, -1, 95, 96, -1, -1, -1, 100, -1, -1, + -1, -1, 115, -1, -1, 98, -1, 110, -1, 102, + 103, -1, -1, -1, -1, 98, -1, -1, -1, 102, + 103, -1, 115, 136, -1, -1, -1, -1, -1, -1, + -1, -1, 115, -1, -1, -1, -1, 140, -1, -1, + -1, -1, -1, 136, -1, -1, -1, 160, -1, -1, + -1, -1, 145, 136, -1, -1, 7, -1, -1, -1, + -1, -1, 145, -1, 167, 16, -1, 160, 19, -1, + -1, -1, -1, -1, -1, -1, -1, 160, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 54, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 102, 103, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 115, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 145, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 160, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 9, -1, 11, 12, 13, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, -1, -1, 40, 41, 42, 43, -1, + -1, -1, -1, 48, -1, -1, -1, -1, -1, -1, + -1, -1, 57, -1, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, + -1, -1, -1, 138, -1, -1, -1, -1, 143, 144, + -1, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, -1, 161, 162, 163, -1, + 165, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 9, -1, 11, 12, 13, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, + -1, 40, 41, 42, 43, -1, -1, -1, -1, 48, + -1, -1, 51, -1, -1, -1, -1, -1, 57, -1, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, -1, -1, -1, -1, -1, -1, + -1, -1, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, -1, -1, -1, -1, 138, + -1, -1, -1, -1, 143, 144, -1, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, -1, 161, 162, 163, -1, 165, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 9, -1, 11, 12, + 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, -1, -1, 40, 41, 42, + 43, -1, -1, -1, -1, 48, -1, -1, 51, 52, + -1, -1, -1, -1, 57, -1, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + -1, -1, -1, -1, -1, -1, -1, -1, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, -1, -1, -1, -1, 138, -1, -1, -1, -1, + 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, -1, 161, 162, + 163, -1, 165, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 9, -1, 11, 12, 13, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, -1, -1, 40, 41, 42, 43, -1, -1, -1, + -1, 48, -1, -1, 51, 52, -1, -1, -1, -1, + 57, -1, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, -1, -1, -1, -1, + -1, -1, -1, -1, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, -1, -1, + -1, 138, -1, -1, -1, -1, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, -1, 161, 162, 163, -1, 165, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, + -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, + -1, 21, 22, -1, -1, -1, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, + 40, 41, 42, 43, -1, -1, -1, -1, 48, -1, + -1, 51, 52, -1, -1, 55, -1, 57, -1, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, -1, -1, -1, -1, -1, -1, 79, + -1, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, -1, -1, -1, -1, 99, + -1, -1, -1, -1, -1, 105, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, -1, -1, -1, -1, 138, -1, + -1, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + -1, 161, 162, 163, -1, 165, -1, -1, -1, 169, + 170, -1, -1, -1, -1, 8, 9, -1, 11, 12, + 13, -1, -1, -1, -1, -1, -1, -1, 21, 22, + -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, -1, -1, 40, 41, 42, + 43, -1, -1, -1, -1, 48, -1, -1, 51, 52, + -1, -1, 55, -1, 57, -1, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + -1, -1, -1, -1, -1, -1, 79, -1, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, -1, -1, -1, -1, 99, -1, -1, -1, + -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, -1, -1, -1, -1, 138, -1, -1, -1, 142, + 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, -1, 161, 162, + 163, -1, 165, -1, -1, -1, 169, 170, -1, -1, + -1, -1, 8, 9, -1, 11, 12, 13, -1, -1, + -1, -1, -1, -1, -1, 21, 22, -1, -1, -1, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, -1, -1, 40, 41, 42, 43, -1, -1, + -1, -1, 48, -1, -1, 51, 52, -1, -1, 55, + -1, 57, -1, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, -1, -1, -1, + -1, -1, -1, 79, -1, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, -1, + -1, -1, -1, 99, -1, -1, -1, -1, -1, 105, + -1, -1, -1, -1, -1, -1, 112, -1, -1, -1, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, -1, -1, + -1, -1, 138, -1, -1, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, -1, 161, 162, 163, -1, 165, + -1, -1, -1, 169, 170, -1, -1, -1, -1, 8, + 9, -1, 11, 12, 13, -1, -1, -1, -1, -1, + -1, -1, 21, 22, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, + -1, 40, 41, 42, 43, -1, -1, -1, -1, 48, + -1, -1, 51, 52, -1, -1, 55, -1, 57, -1, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, -1, -1, -1, -1, -1, -1, + 79, -1, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, -1, -1, -1, -1, + 99, -1, -1, -1, -1, -1, 105, -1, -1, -1, + -1, -1, -1, 112, -1, -1, -1, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, -1, -1, -1, -1, 138, + -1, -1, -1, 142, 143, 144, -1, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, -1, 161, 162, 163, -1, 165, -1, -1, -1, + 169, 170, -1, -1, -1, -1, 8, 9, -1, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, 21, + 22, -1, -1, -1, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, -1, -1, 40, 41, + 42, 43, -1, -1, -1, -1, 48, -1, -1, 51, + 52, -1, -1, 55, -1, 57, -1, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, -1, -1, -1, -1, -1, -1, 79, -1, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, -1, -1, -1, -1, 99, -1, -1, + -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, + 112, -1, -1, -1, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, -1, -1, -1, -1, 138, -1, -1, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, -1, 161, + 162, 163, -1, 165, -1, -1, -1, 169, 170, -1, + -1, -1, -1, 8, 9, -1, 11, 12, 13, -1, + -1, -1, -1, -1, -1, -1, 21, 22, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, -1, -1, 40, 41, 42, 43, -1, + -1, -1, -1, 48, -1, -1, 51, 52, -1, -1, + 55, -1, 57, -1, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, -1, -1, + -1, -1, -1, -1, 79, -1, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + -1, -1, -1, -1, 99, -1, -1, -1, -1, -1, + 105, -1, -1, -1, -1, -1, -1, 112, -1, -1, + -1, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, + -1, -1, -1, 138, -1, -1, -1, 142, 143, 144, + -1, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, -1, 161, 162, 163, -1, + 165, -1, -1, -1, 169, 170, -1, -1, -1, -1, + 8, 9, -1, 11, 12, 13, -1, -1, -1, -1, + -1, -1, -1, 21, 22, -1, -1, -1, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + -1, -1, 40, 41, 42, 43, -1, -1, -1, -1, + 48, -1, -1, 51, 52, -1, -1, 55, -1, 57, + -1, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, -1, -1, -1, -1, -1, + -1, 79, -1, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, -1, -1, -1, + -1, 99, -1, -1, -1, -1, -1, 105, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, -1, -1, -1, + 138, -1, -1, -1, 142, 143, 144, -1, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, -1, 161, 162, 163, -1, 165, -1, -1, + -1, 169, 170, -1, -1, -1, -1, 8, 9, -1, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, + 21, 22, -1, -1, -1, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, -1, -1, 40, + 41, 42, 43, -1, -1, -1, -1, 48, -1, -1, + 51, 52, -1, -1, 55, -1, 57, -1, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, -1, -1, -1, -1, -1, -1, 79, -1, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, -1, -1, -1, -1, 99, -1, + -1, -1, -1, -1, 105, -1, -1, -1, -1, -1, + -1, 112, -1, -1, -1, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, -1, -1, -1, -1, 138, -1, -1, + -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, -1, + 161, 162, 163, -1, 165, -1, -1, -1, 169, 170, + -1, -1, -1, -1, 7, -1, 9, -1, 11, 12, + 13, -1, -1, 16, -1, -1, 19, -1, -1, -1, + -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, -1, -1, 40, 41, 42, + 43, -1, -1, -1, 47, 48, -1, -1, 51, -1, + -1, 54, -1, -1, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, -1, -1, -1, -1, -1, -1, -1, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, -1, -1, -1, 98, -1, -1, -1, 102, + 103, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, -1, -1, 136, -1, 138, -1, -1, -1, -1, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, -1, 165, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7, -1, 9, -1, 11, 12, 13, -1, + -1, 16, -1, -1, 19, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, -1, -1, 40, 41, 42, 43, -1, + -1, -1, 47, 48, -1, -1, 51, -1, -1, 54, + -1, -1, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, + -1, -1, -1, -1, -1, -1, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + -1, -1, -1, 98, -1, -1, -1, 102, 103, -1, + -1, -1, -1, -1, -1, -1, 111, -1, -1, -1, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, + -1, 136, -1, 138, -1, -1, -1, -1, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, -1, + 165, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 7, -1, 9, -1, 11, 12, 13, -1, -1, 16, + -1, -1, 19, -1, -1, -1, -1, -1, -1, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, -1, -1, 40, 41, 42, 43, -1, -1, -1, + 47, 48, -1, -1, 51, -1, -1, 54, -1, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, + -1, -1, -1, -1, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, -1, -1, + -1, 98, -1, -1, -1, 102, 103, -1, -1, -1, + -1, -1, -1, -1, 111, -1, -1, -1, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, -1, -1, 136, + -1, 138, -1, -1, -1, -1, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, -1, 165, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, + 9, -1, 11, 12, 13, -1, -1, 16, -1, -1, + 19, -1, -1, -1, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, + -1, 40, 41, 42, 43, -1, -1, -1, 47, 48, + -1, -1, 51, -1, -1, 54, -1, -1, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, + -1, -1, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, -1, -1, -1, 98, + -1, -1, -1, 102, 103, -1, -1, -1, -1, -1, + -1, -1, 111, -1, -1, -1, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, -1, -1, 136, -1, 138, + -1, -1, -1, -1, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, -1, 165, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7, -1, 9, -1, + 11, 12, 13, -1, -1, 16, -1, -1, 19, -1, + -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, -1, -1, 40, + 41, 42, 43, -1, -1, -1, 47, 48, -1, -1, + 51, -1, -1, 54, -1, -1, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, -1, -1, -1, 98, -1, -1, + -1, 102, 103, -1, -1, 106, -1, -1, -1, -1, + -1, -1, -1, -1, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, -1, 136, -1, 138, -1, -1, + -1, -1, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, -1, 165, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7, 8, 9, -1, 11, 12, + 13, -1, -1, 16, -1, -1, 19, -1, 21, 22, + -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, -1, -1, 40, 41, 42, + 43, -1, -1, -1, 47, 48, -1, -1, 51, 52, + -1, 54, 55, -1, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, -1, -1, -1, -1, -1, 79, -1, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, -1, -1, -1, 98, 99, -1, -1, 102, + 103, -1, 105, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, -1, -1, 136, -1, 138, -1, -1, -1, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, -1, 165, -1, -1, -1, 169, 170, -1, -1, + -1, -1, 7, 8, 9, -1, 11, 12, 13, -1, + -1, 16, -1, -1, 19, -1, 21, 22, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, -1, -1, 40, 41, 42, 43, -1, + -1, -1, 47, 48, -1, -1, 51, 52, -1, 54, + 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, + -1, -1, -1, -1, 79, -1, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + -1, -1, -1, 98, 99, -1, -1, 102, 103, -1, + 105, 106, -1, -1, -1, -1, -1, -1, -1, -1, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + -1, 136, -1, 138, -1, -1, -1, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, -1, + 165, -1, -1, -1, 169, 170, -1, -1, -1, -1, + 7, 8, 9, 10, 11, 12, 13, -1, 15, 16, + -1, -1, 19, 20, 21, 22, 23, 24, -1, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, -1, 40, 41, 42, 43, -1, -1, -1, + 47, 48, 49, -1, 51, 52, 53, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, -1, -1, 76, + -1, -1, 79, -1, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, -1, -1, + -1, 98, 99, -1, -1, 102, 103, -1, 105, 106, + -1, 108, -1, -1, -1, -1, -1, -1, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, -1, 136, + -1, 138, -1, -1, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, -1, 165, 166, + -1, -1, 169, 170, -1, -1, -1, -1, 7, 8, + 9, 10, 11, 12, 13, -1, 15, 16, -1, -1, + 19, 20, 21, 22, 23, 24, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + -1, 40, 41, 42, 43, -1, -1, -1, 47, 48, + 49, -1, 51, 52, 53, 54, 55, -1, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, -1, -1, 76, -1, -1, + 79, -1, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, -1, -1, -1, 98, + 99, -1, -1, 102, 103, -1, 105, 106, -1, 108, + -1, -1, -1, -1, -1, -1, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, -1, 136, -1, 138, + -1, -1, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, -1, 165, 166, -1, -1, + 169, 170, -1, -1, -1, -1, 7, 8, 9, 10, + 11, 12, 13, -1, 15, 16, -1, -1, 19, 20, + 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, -1, 40, + 41, 42, 43, -1, -1, -1, 47, 48, 49, -1, + 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, -1, -1, 76, -1, -1, 79, -1, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, -1, -1, -1, 98, 99, -1, + -1, 102, 103, -1, 105, 106, -1, 108, -1, -1, + 111, -1, -1, -1, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, -1, 136, -1, 138, -1, -1, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, -1, 165, 166, -1, -1, 169, 170, + -1, -1, -1, -1, 7, 8, 9, 10, 11, 12, + 13, -1, 15, 16, -1, -1, 19, 20, 21, 22, + 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, -1, 40, 41, 42, + 43, -1, -1, -1, 47, 48, 49, -1, 51, 52, + 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, -1, -1, 76, -1, -1, 79, -1, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, -1, -1, -1, 98, 99, -1, -1, 102, + 103, -1, 105, 106, -1, 108, -1, -1, 111, -1, + -1, -1, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, -1, 136, -1, 138, -1, -1, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, -1, 165, 166, -1, -1, 169, 170, -1, -1, + -1, -1, 7, 8, 9, 10, 11, 12, 13, -1, + 15, 16, -1, -1, 19, 20, 21, 22, 23, 24, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, -1, 40, 41, 42, 43, -1, + -1, -1, 47, 48, 49, -1, 51, 52, 53, 54, + 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, + -1, 76, -1, -1, 79, -1, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + -1, -1, -1, 98, 99, -1, -1, 102, 103, -1, + 105, 106, -1, 108, -1, -1, 111, -1, -1, -1, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + -1, 136, -1, 138, -1, -1, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, -1, + 165, 166, -1, -1, 169, 170, -1, -1, -1, -1, + 7, 8, 9, 10, 11, 12, 13, -1, 15, 16, + -1, -1, 19, 20, 21, 22, 23, 24, -1, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, -1, 40, 41, 42, 43, -1, -1, -1, + 47, 48, 49, -1, 51, 52, 53, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, -1, -1, 76, + -1, -1, 79, -1, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, -1, -1, + -1, 98, 99, -1, -1, 102, 103, -1, 105, 106, + -1, 108, -1, -1, 111, -1, -1, -1, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, -1, 136, + -1, 138, -1, -1, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, -1, 165, 166, + -1, -1, 169, 170, -1, -1, -1, -1, - 14, 3, 12, 14, 55, 3, 15, 15, 3, 54, - 59, 15, 60, 3, 15, 15, 12, 3, 45, 8, - 55, 15, 3, 3, 41, 12, 14, 34, 12, 14, - 3, 14, 35, 12, 12, 73, 3, 55, 35, 15, - 12, 15, 12, 12, 12, 21, 20, -1, -1, 15, - 15, 15, 12, 17, 15, 20, 17, 14, 12, 15, - 15, 14, 28, 18, 15, 15, 14, 18, 14, 25, - 14, 3, -1, 15, 14, 14, 26, 49, 14, 49, - 49, 49, 24, -1, -1, -1, 15, 15, 51, 49, - 19, 19, 55, 15, 15, 49, 36, 19, 15, 15, - 14, 22, 15, 19, 14, 62, 23, 14, -1, 62, - 14, -1, 15, 14, 62, 28, 62, 30, 14, 14, - 64, 15, 36, 62, 15, 28, 62, 30, 14, 14, - 31, 32, 36, 15, 28, -1, 30, 28, 3, 30, - 36, 37, -1, -1, 58, 14, 28, -1, 30, 14, - 36, 61, 47, 14, 58, 65, -1, 64, 43, 3, - -1, 46, -1, -1, -1, 72, -1, 36, 37, -1, - 14, 36, 58, -1, -1, -1, 71, 42, -1, -1, - -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 36, -1, -1, -1, -1, -1, 42, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 14, -1, -1, -1, -1, -1, - -1, 75, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 31, 32, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 82, -1, -1}; + 12, 14, 3, 3, 3, 54, 15, 14, 55, 15, + 15, 15, 15, 59, 3, 60, 55, 12, 12, 3, + 3, 14, 41, 34, 15, 3, 8, 45, 14, 3, + 3, 12, 12, 35, 55, 73, 12, 14, 35, 14, + 12, -1, -1, 12, 15, 15, 17, 17, 12, 12, + 15, 12, -1, 15, -1, 15, 15, 15, 15, 21, + 20, 20, 19, 28, 15, 23, 15, 15, 14, 12, + 14, -1, 51, 3, 25, 24, 55, 49, 26, 14, + 49, 15, 15, 14, 18, 49, 49, 62, 49, 22, + 14, 14, 36, 15, 15, 15, 15, 19, 18, 15, + 19, 14, 14, 19, 14, 14, 49, 28, 14, 30, + 14, 14, -1, 15, 14, -1, -1, -1, 64, 14, + -1, 31, 32, 14, 14, -1, 28, 62, 30, 15, + -1, 62, 36, 36, 37, 47, 15, 43, 62, 62, + 46, 36, 28, 14, 30, 36, 36, 37, -1, 28, + -1, 30, 61, 15, 58, 14, 65, -1, 71, 71, + 31, 32, 3, 58, 64, -1, 28, 58, 30, -1, + -1, -1, 72, 14, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 36, -1, -1, -1, -1, + -1, 42, -1, 62, -1, -1, 47, -1, -1, -1, + -1, 82, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 14, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 36, + -1, -1, -1, -1, -1, 42, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 75, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; QT_END_NAMESPACE diff --git a/src/libs/glsl/glslparsertable_p.h b/src/libs/glsl/glslparsertable_p.h index b046b5df7a..8abd115735 100644 --- a/src/libs/glsl/glslparsertable_p.h +++ b/src/libs/glsl/glslparsertable_p.h @@ -3,8 +3,9 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of Qt Creator. +** This file is part of the Qt Toolkit. ** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -21,6 +22,8 @@ ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** +** $QT_END_LICENSE$ +** ****************************************************************************/ // @@ -35,231 +38,234 @@ // // This file was generated by qlalr - DO NOT EDIT! -#pragma once +#ifndef GLSLPARSERTABLE_P_H +#define GLSLPARSERTABLE_P_H -#include <qglobal.h> +#include <QtCore/qglobal.h> QT_BEGIN_NAMESPACE class GLSLParserTable { public: - enum VariousConstants { - EOF_SYMBOL = 0, - T_ADD_ASSIGN = 3, - T_AMPERSAND = 4, - T_AND_ASSIGN = 5, - T_AND_OP = 6, - T_ATTRIBUTE = 7, - T_BANG = 8, - T_BOOL = 9, - T_BREAK = 10, - T_BVEC2 = 11, - T_BVEC3 = 12, - T_BVEC4 = 13, - T_CARET = 14, - T_CASE = 15, - T_CENTROID = 16, - T_COLON = 17, - T_COMMA = 18, - T_COMMENT = 172, - T_CONST = 19, - T_CONTINUE = 20, - T_DASH = 21, - T_DEC_OP = 22, - T_DEFAULT = 23, - T_DISCARD = 24, - T_DIV_ASSIGN = 25, - T_DMAT2 = 26, - T_DMAT2X2 = 27, - T_DMAT2X3 = 28, - T_DMAT2X4 = 29, - T_DMAT3 = 30, - T_DMAT3X2 = 31, - T_DMAT3X3 = 32, - T_DMAT3X4 = 33, - T_DMAT4 = 34, - T_DMAT4X2 = 35, - T_DMAT4X3 = 36, - T_DMAT4X4 = 37, - T_DO = 38, - T_DOT = 39, - T_DOUBLE = 40, - T_DVEC2 = 41, - T_DVEC3 = 42, - T_DVEC4 = 43, - T_ELSE = 44, - T_EQUAL = 45, - T_EQ_OP = 46, - T_ERROR = 173, - T_FALSE = 170, - T_FEED_EXPRESSION = 2, - T_FEED_GLSL = 1, - T_FLAT = 47, - T_FLOAT = 48, - T_FOR = 49, - T_GE_OP = 50, - T_HIGHP = 51, - T_IDENTIFIER = 52, - T_IF = 53, - T_IN = 54, - T_INC_OP = 55, - T_INOUT = 56, - T_INT = 57, - T_INVARIANT = 58, - T_ISAMPLER1D = 59, - T_ISAMPLER1DARRAY = 60, - T_ISAMPLER2D = 61, - T_ISAMPLER2DARRAY = 62, - T_ISAMPLER2DMS = 63, - T_ISAMPLER2DMSARRAY = 64, - T_ISAMPLER2DRECT = 65, - T_ISAMPLER3D = 66, - T_ISAMPLERBUFFER = 67, - T_ISAMPLERCUBE = 68, - T_ISAMPLERCUBEARRAY = 69, - T_IVEC2 = 70, - T_IVEC3 = 71, - T_IVEC4 = 72, - T_LAYOUT = 73, - T_LEFT_ANGLE = 74, - T_LEFT_ASSIGN = 75, - T_LEFT_BRACE = 76, - T_LEFT_BRACKET = 77, - T_LEFT_OP = 78, - T_LEFT_PAREN = 79, - T_LE_OP = 80, - T_LOWP = 81, - T_MAT2 = 82, - T_MAT2X2 = 83, - T_MAT2X3 = 84, - T_MAT2X4 = 85, - T_MAT3 = 86, - T_MAT3X2 = 87, - T_MAT3X3 = 88, - T_MAT3X4 = 89, - T_MAT4 = 90, - T_MAT4X2 = 91, - T_MAT4X3 = 92, - T_MAT4X4 = 93, - T_MEDIUMP = 94, - T_MOD_ASSIGN = 95, - T_MUL_ASSIGN = 96, - T_NE_OP = 97, - T_NOPERSPECTIVE = 98, - T_NUMBER = 99, - T_OR_ASSIGN = 100, - T_OR_OP = 101, - T_OUT = 102, - T_PATCH = 103, - T_PERCENT = 104, - T_PLUS = 105, - T_PRECISION = 106, - T_PREPROC = 171, - T_QUESTION = 107, - T_RESERVED = 174, - T_RETURN = 108, - T_RIGHT_ANGLE = 109, - T_RIGHT_ASSIGN = 110, - T_RIGHT_BRACE = 111, - T_RIGHT_BRACKET = 112, - T_RIGHT_OP = 113, - T_RIGHT_PAREN = 114, - T_SAMPLE = 115, - T_SAMPLER1D = 116, - T_SAMPLER1DARRAY = 117, - T_SAMPLER1DARRAYSHADOW = 118, - T_SAMPLER1DSHADOW = 119, - T_SAMPLER2D = 120, - T_SAMPLER2DARRAY = 121, - T_SAMPLER2DARRAYSHADOW = 122, - T_SAMPLER2DMS = 123, - T_SAMPLER2DMSARRAY = 124, - T_SAMPLER2DRECT = 125, - T_SAMPLER2DRECTSHADOW = 126, - T_SAMPLER2DSHADOW = 127, - T_SAMPLER3D = 128, - T_SAMPLERBUFFER = 129, - T_SAMPLERCUBE = 130, - T_SAMPLERCUBEARRAY = 131, - T_SAMPLERCUBEARRAYSHADOW = 132, - T_SAMPLERCUBESHADOW = 133, - T_SEMICOLON = 134, - T_SLASH = 135, - T_SMOOTH = 136, - T_STAR = 137, - T_STRUCT = 138, - T_SUBROUTINE = 139, - T_SUB_ASSIGN = 140, - T_SWITCH = 141, - T_TILDE = 142, - T_TRUE = 169, - T_TYPE_NAME = 143, - T_UINT = 144, - T_UNIFORM = 145, - T_USAMPLER1D = 146, - T_USAMPLER1DARRAY = 147, - T_USAMPLER2D = 148, - T_USAMPLER2DARRAY = 149, - T_USAMPLER2DMS = 150, - T_USAMPLER2DMSARRAY = 151, - T_USAMPLER2DRECT = 152, - T_USAMPLER3D = 153, - T_USAMPLERBUFFER = 154, - T_USAMPLERCUBE = 155, - T_USAMPLERCUBEARRAY = 156, - T_UVEC2 = 157, - T_UVEC3 = 158, - T_UVEC4 = 159, - T_VARYING = 160, - T_VEC2 = 161, - T_VEC3 = 162, - T_VEC4 = 163, - T_VERTICAL_BAR = 164, - T_VOID = 165, - T_WHILE = 166, - T_XOR_ASSIGN = 167, - T_XOR_OP = 168, + enum VariousConstants { + EOF_SYMBOL = 0, + T_ADD_ASSIGN = 3, + T_AMPERSAND = 4, + T_AND_ASSIGN = 5, + T_AND_OP = 6, + T_ATTRIBUTE = 7, + T_BANG = 8, + T_BOOL = 9, + T_BREAK = 10, + T_BVEC2 = 11, + T_BVEC3 = 12, + T_BVEC4 = 13, + T_CARET = 14, + T_CASE = 15, + T_CENTROID = 16, + T_COLON = 17, + T_COMMA = 18, + T_COMMENT = 172, + T_CONST = 19, + T_CONTINUE = 20, + T_DASH = 21, + T_DEC_OP = 22, + T_DEFAULT = 23, + T_DISCARD = 24, + T_DIV_ASSIGN = 25, + T_DMAT2 = 26, + T_DMAT2X2 = 27, + T_DMAT2X3 = 28, + T_DMAT2X4 = 29, + T_DMAT3 = 30, + T_DMAT3X2 = 31, + T_DMAT3X3 = 32, + T_DMAT3X4 = 33, + T_DMAT4 = 34, + T_DMAT4X2 = 35, + T_DMAT4X3 = 36, + T_DMAT4X4 = 37, + T_DO = 38, + T_DOT = 39, + T_DOUBLE = 40, + T_DVEC2 = 41, + T_DVEC3 = 42, + T_DVEC4 = 43, + T_ELSE = 44, + T_EQUAL = 45, + T_EQ_OP = 46, + T_ERROR = 173, + T_FALSE = 170, + T_FEED_EXPRESSION = 2, + T_FEED_GLSL = 1, + T_FLAT = 47, + T_FLOAT = 48, + T_FOR = 49, + T_GE_OP = 50, + T_HIGHP = 51, + T_IDENTIFIER = 52, + T_IF = 53, + T_IN = 54, + T_INC_OP = 55, + T_INOUT = 56, + T_INT = 57, + T_INVARIANT = 58, + T_ISAMPLER1D = 59, + T_ISAMPLER1DARRAY = 60, + T_ISAMPLER2D = 61, + T_ISAMPLER2DARRAY = 62, + T_ISAMPLER2DMS = 63, + T_ISAMPLER2DMSARRAY = 64, + T_ISAMPLER2DRECT = 65, + T_ISAMPLER3D = 66, + T_ISAMPLERBUFFER = 67, + T_ISAMPLERCUBE = 68, + T_ISAMPLERCUBEARRAY = 69, + T_IVEC2 = 70, + T_IVEC3 = 71, + T_IVEC4 = 72, + T_LAYOUT = 73, + T_LEFT_ANGLE = 74, + T_LEFT_ASSIGN = 75, + T_LEFT_BRACE = 76, + T_LEFT_BRACKET = 77, + T_LEFT_OP = 78, + T_LEFT_PAREN = 79, + T_LE_OP = 80, + T_LOWP = 81, + T_MAT2 = 82, + T_MAT2X2 = 83, + T_MAT2X3 = 84, + T_MAT2X4 = 85, + T_MAT3 = 86, + T_MAT3X2 = 87, + T_MAT3X3 = 88, + T_MAT3X4 = 89, + T_MAT4 = 90, + T_MAT4X2 = 91, + T_MAT4X3 = 92, + T_MAT4X4 = 93, + T_MEDIUMP = 94, + T_MOD_ASSIGN = 95, + T_MUL_ASSIGN = 96, + T_NE_OP = 97, + T_NOPERSPECTIVE = 98, + T_NUMBER = 99, + T_OR_ASSIGN = 100, + T_OR_OP = 101, + T_OUT = 102, + T_PATCH = 103, + T_PERCENT = 104, + T_PLUS = 105, + T_PRECISION = 106, + T_PREPROC = 171, + T_QUESTION = 107, + T_RESERVED = 174, + T_RETURN = 108, + T_RIGHT_ANGLE = 109, + T_RIGHT_ASSIGN = 110, + T_RIGHT_BRACE = 111, + T_RIGHT_BRACKET = 112, + T_RIGHT_OP = 113, + T_RIGHT_PAREN = 114, + T_SAMPLE = 115, + T_SAMPLER1D = 116, + T_SAMPLER1DARRAY = 117, + T_SAMPLER1DARRAYSHADOW = 118, + T_SAMPLER1DSHADOW = 119, + T_SAMPLER2D = 120, + T_SAMPLER2DARRAY = 121, + T_SAMPLER2DARRAYSHADOW = 122, + T_SAMPLER2DMS = 123, + T_SAMPLER2DMSARRAY = 124, + T_SAMPLER2DRECT = 125, + T_SAMPLER2DRECTSHADOW = 126, + T_SAMPLER2DSHADOW = 127, + T_SAMPLER3D = 128, + T_SAMPLERBUFFER = 129, + T_SAMPLERCUBE = 130, + T_SAMPLERCUBEARRAY = 131, + T_SAMPLERCUBEARRAYSHADOW = 132, + T_SAMPLERCUBESHADOW = 133, + T_SEMICOLON = 134, + T_SLASH = 135, + T_SMOOTH = 136, + T_STAR = 137, + T_STRUCT = 138, + T_SUBROUTINE = 139, + T_SUB_ASSIGN = 140, + T_SWITCH = 141, + T_TILDE = 142, + T_TRUE = 169, + T_TYPE_NAME = 143, + T_UINT = 144, + T_UNIFORM = 145, + T_USAMPLER1D = 146, + T_USAMPLER1DARRAY = 147, + T_USAMPLER2D = 148, + T_USAMPLER2DARRAY = 149, + T_USAMPLER2DMS = 150, + T_USAMPLER2DMSARRAY = 151, + T_USAMPLER2DRECT = 152, + T_USAMPLER3D = 153, + T_USAMPLERBUFFER = 154, + T_USAMPLERCUBE = 155, + T_USAMPLERCUBEARRAY = 156, + T_UVEC2 = 157, + T_UVEC3 = 158, + T_UVEC4 = 159, + T_VARYING = 160, + T_VEC2 = 161, + T_VEC3 = 162, + T_VEC4 = 163, + T_VERTICAL_BAR = 164, + T_VOID = 165, + T_WHILE = 166, + T_XOR_ASSIGN = 167, + T_XOR_OP = 168, - ACCEPT_STATE = 462, - RULE_COUNT = 316, - STATE_COUNT = 463, - TERMINAL_COUNT = 175, - NON_TERMINAL_COUNT = 85, + ACCEPT_STATE = 462, + RULE_COUNT = 316, + STATE_COUNT = 463, + TERMINAL_COUNT = 175, + NON_TERMINAL_COUNT = 85, - GOTO_INDEX_OFFSET = 463, - GOTO_INFO_OFFSET = 4681, - GOTO_CHECK_OFFSET = 4681 - }; + GOTO_INDEX_OFFSET = 463, + GOTO_INFO_OFFSET = 4708, + GOTO_CHECK_OFFSET = 4708 + }; - static const char *const spell []; - static const short lhs []; - static const short rhs []; - static const short goto_default []; - static const short action_default []; - static const short action_index []; - static const short action_info []; - static const short action_check []; + static const char *const spell[]; + static const short lhs[]; + static const short rhs[]; + static const short goto_default[]; + static const short action_default[]; + static const short action_index[]; + static const short action_info[]; + static const short action_check[]; - static inline int nt_action (int state, int nt) - { - const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt; - if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt) - return goto_default [nt]; + static inline int nt_action (int state, int nt) + { + const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt; + if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt) + return goto_default [nt]; - return action_info [GOTO_INFO_OFFSET + yyn]; - } + return action_info [GOTO_INFO_OFFSET + yyn]; + } - static inline int t_action (int state, int token) - { - const int yyn = action_index [state] + token; + static inline int t_action (int state, int token) + { + const int yyn = action_index [state] + token; - if (yyn < 0 || action_check [yyn] != token) - return - action_default [state]; + if (yyn < 0 || action_check [yyn] != token) + return - action_default [state]; - return action_info [yyn]; - } + return action_info [yyn]; + } }; QT_END_NAMESPACE +#endif // GLSLPARSERTABLE_P_H + diff --git a/src/libs/utils/benchmarker.cpp b/src/libs/utils/benchmarker.cpp index 61f4f37d19..72a20293e5 100644 --- a/src/libs/utils/benchmarker.cpp +++ b/src/libs/utils/benchmarker.cpp @@ -33,6 +33,13 @@ namespace Utils { Benchmarker::Benchmarker(const QString &testsuite, const QString &testcase, const QString &tagData) : + Benchmarker(benchmarksLog(), testsuite, testcase, tagData) +{ } + +Benchmarker::Benchmarker(const QLoggingCategory &cat, + const QString &testsuite, const QString &testcase, + const QString &tagData) : + m_category(cat), m_tagData(tagData), m_testsuite(testsuite), m_testcase(testcase) @@ -49,17 +56,23 @@ Benchmarker::~Benchmarker() void Benchmarker::report(qint64 ms) { m_timer.invalidate(); - report(m_testsuite, m_testcase, ms, m_tagData); + report(m_category, m_testsuite, m_testcase, ms, m_tagData); +} + +void Benchmarker::report(const QString &testsuite, + const QString &testcase, qint64 ms, const QString &tags) +{ + report(benchmarksLog(), testsuite, testcase, ms, tags); } -void Benchmarker::report(const QString &testsuite, const QString &testcase, qint64 ms, - const QString &tags) +void Benchmarker::report(const QLoggingCategory &cat, const QString &testsuite, const QString &testcase, + qint64 ms, const QString &tags) { QString t = "unit=ms"; if (!tags.isEmpty()) t += "," + tags; - qCDebug(benchmarksLog, "%s::%s: %lld { %s }", + qCDebug(cat, "%s::%s: %lld { %s }", testsuite.toUtf8().data(), testcase.toUtf8().data(), ms, t.toUtf8().data()); } diff --git a/src/libs/utils/benchmarker.h b/src/libs/utils/benchmarker.h index bcff6d341c..65dfe0af8e 100644 --- a/src/libs/utils/benchmarker.h +++ b/src/libs/utils/benchmarker.h @@ -30,20 +30,30 @@ #include <QString> #include <QElapsedTimer> +QT_BEGIN_NAMESPACE +class QLoggingCategory; +QT_END_NAMESPACE + namespace Utils { class QTCREATOR_UTILS_EXPORT Benchmarker { public: Benchmarker(const QString &testsuite, const QString &testcase, - const QString &tags = QString()); + const QString &tagData = QString()); + Benchmarker(const QLoggingCategory &cat, const QString &testsuite, const QString &testcase, + const QString &tagData = QString()); ~Benchmarker(); void report(qint64 ms); - static void report(const QString &testsuite, const QString &testcase, qint64 ms, - const QString &tags = QString()); + static void report(const QString &testsuite, const QString &testcase, + qint64 ms, const QString &tags = QString()); + static void report(const QLoggingCategory &cat, + const QString &testsuite, const QString &testcase, + qint64 ms, const QString &tags = QString()); private: + const QLoggingCategory &m_category; QElapsedTimer m_timer; QString m_tagData; QString m_testsuite; diff --git a/src/libs/utils/camelhumpmatcher.cpp b/src/libs/utils/camelhumpmatcher.cpp index cb99cff137..b82cd2d899 100644 --- a/src/libs/utils/camelhumpmatcher.cpp +++ b/src/libs/utils/camelhumpmatcher.cpp @@ -65,6 +65,7 @@ QRegularExpression CamelHumpMatcher::createCamelHumpRegExp( */ QString keyRegExp; + QString plainRegExp; bool first = true; const QChar asterisk = '*'; const QChar question = '?'; @@ -76,27 +77,33 @@ QRegularExpression CamelHumpMatcher::createCamelHumpRegExp( keyRegExp += "(?:"; for (const QChar &c : pattern) { if (!c.isLetter()) { - if (c == question) + if (c == question) { keyRegExp += '.'; - else if (c == asterisk) + plainRegExp += '.'; + } else if (c == asterisk) { keyRegExp += ".*"; - else - keyRegExp += '(' + QRegularExpression::escape(c) + ')'; + plainRegExp += ".*"; + } else { + const QString escaped = QRegularExpression::escape(c); + keyRegExp += '(' + escaped + ')'; + plainRegExp += escaped; + } } else if (caseSensitivity == CaseSensitivity::CaseInsensitive || (caseSensitivity == CaseSensitivity::FirstLetterCaseSensitive && !first)) { + const QString upper = QRegularExpression::escape(c.toUpper()); + const QString lower = QRegularExpression::escape(c.toLower()); keyRegExp += "(?:"; keyRegExp += first ? uppercaseWordFirst : uppercaseWordContinuation; - keyRegExp += '(' + QRegularExpression::escape(c.toUpper()); + keyRegExp += '(' + upper + ')'; if (first) { - keyRegExp += '|' + lowercaseWordFirst + QRegularExpression::escape(c.toLower()) + ')'; + keyRegExp += '|' + lowercaseWordFirst + '(' + lower + ')'; } else { - keyRegExp += ")|" + lowercaseWordContinuation; - keyRegExp += '(' + QRegularExpression::escape(c.toLower()) + ")|"; - keyRegExp += upperSnakeWordContinuation; - keyRegExp += '(' + QRegularExpression::escape(c.toUpper()) + ')'; + keyRegExp += '|' + lowercaseWordContinuation + '(' + lower + ')'; + keyRegExp += '|' + upperSnakeWordContinuation + '(' + upper + ')'; } keyRegExp += ')'; + plainRegExp += '[' + upper + lower + ']'; } else { if (!first) { if (c.isUpper()) @@ -104,12 +111,14 @@ QRegularExpression CamelHumpMatcher::createCamelHumpRegExp( else keyRegExp += lowercaseWordContinuation; } - keyRegExp += QRegularExpression::escape(c); + const QString escaped = QRegularExpression::escape(c); + keyRegExp += escaped; + plainRegExp += escaped; } first = false; } - keyRegExp += ")|(" + QRegularExpression::escape(pattern) + ')'; + keyRegExp += ")|(" + plainRegExp + ')'; return QRegularExpression(keyRegExp); } diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index 6ea2099211..2c0cdee733 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -423,6 +423,8 @@ SynchronousProcessResponse ShellCommand::runSynchronous(const FileName &binary, connect(&process, &Utils::SynchronousProcess::stdErrBuffered, this, [this, proxy](const QString &text) { + if (d->m_progressParser) + d->m_progressParser->parseProgress(text); if (!(d->m_flags & SuppressStdErr)) proxy->appendError(text); if (d->m_progressiveOutput) diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp index ee4f14ae93..ac518bdd21 100644 --- a/src/plugins/android/androidsdkmanager.cpp +++ b/src/plugins/android/androidsdkmanager.cpp @@ -33,6 +33,7 @@ #include "utils/environment.h" #include <QLoggingCategory> +#include <QRegularExpression> #include <QSettings> namespace { @@ -172,8 +173,9 @@ void SdkManagerOutputParser::parsePackageListing(const QString &output) } }; - foreach (QString outputLine, output.split('\n')) { - MarkerTag marker = parseMarkers(outputLine); + QRegularExpression delimiters("[\n\r]"); + foreach (QString outputLine, output.split(delimiters)) { + MarkerTag marker = parseMarkers(outputLine.trimmed()); if (marker & SectionMarkers) { // Section marker found. Update the current section being parsed. diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index 912a563fa8..89f3e1a974 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -77,7 +77,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) TestResultPtr testResult = TestResultPtr(new GTestResult(m_projectFile)); testResult->setResult(Result::MessageInternal); testResult->setDescription(m_description); - m_futureInterface.reportResult(testResult); + reportResult(testResult); m_description.clear(); } else if (disabledTests.exactMatch(line)) { TestResultPtr testResult = TestResultPtr(new GTestResult(m_projectFile)); @@ -85,7 +85,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) int disabled = disabledTests.cap(1).toInt(); testResult->setDescription(tr("You have %n disabled test(s).", 0, disabled)); testResult->setLine(disabled); // misuse line property to hold number of disabled - m_futureInterface.reportResult(testResult); + reportResult(testResult); m_description.clear(); } return; @@ -95,7 +95,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) GTestResult *testResult = createDefaultResult(); testResult->setResult(Result::MessageTestCaseEnd); testResult->setDescription(tr("Test execution took %1").arg(testEnds.cap(2))); - m_futureInterface.reportResult(TestResultPtr(testResult)); + reportResult(TestResultPtr(testResult)); m_currentTestName.clear(); m_currentTestSet.clear(); } else if (newTestStarts.exactMatch(line)) { @@ -108,24 +108,24 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) } else { testResult->setDescription(tr("Executing test case %1").arg(m_currentTestName)); } - m_futureInterface.reportResult(testResult); + reportResult(testResult); } else if (newTestSetStarts.exactMatch(line)) { setCurrentTestSet(newTestSetStarts.cap(1)); TestResultPtr testResult = TestResultPtr(new GTestResult(m_projectFile)); testResult->setResult(Result::MessageCurrentTest); testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet)); - m_futureInterface.reportResult(testResult); + reportResult(testResult); m_description.clear(); } else if (testSetSuccess.exactMatch(line)) { GTestResult *testResult = createDefaultResult(); testResult->setResult(Result::Pass); testResult->setDescription(m_description); - m_futureInterface.reportResult(TestResultPtr(testResult)); + reportResult(TestResultPtr(testResult)); m_description.clear(); testResult = createDefaultResult(); testResult->setResult(Result::MessageInternal); testResult->setDescription(tr("Execution took %1.").arg(testSetSuccess.cap(2))); - m_futureInterface.reportResult(TestResultPtr(testResult)); + reportResult(TestResultPtr(testResult)); m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1); } else if (testSetFail.exactMatch(line)) { GTestResult *testResult = createDefaultResult(); @@ -149,12 +149,12 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) } } } - m_futureInterface.reportResult(TestResultPtr(testResult)); + reportResult(TestResultPtr(testResult)); m_description.clear(); testResult = createDefaultResult(); testResult->setResult(Result::MessageInternal); testResult->setDescription(tr("Execution took %1.").arg(testSetFail.cap(2))); - m_futureInterface.reportResult(TestResultPtr(testResult)); + reportResult(TestResultPtr(testResult)); m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1); } } diff --git a/src/plugins/autotest/qtest/qttestconfiguration.cpp b/src/plugins/autotest/qtest/qttestconfiguration.cpp index bb8f62aacf..157c9873e5 100644 --- a/src/plugins/autotest/qtest/qttestconfiguration.cpp +++ b/src/plugins/autotest/qtest/qttestconfiguration.cpp @@ -46,9 +46,9 @@ TestOutputReader *QtTestConfiguration::outputReader(const QFutureInterface<TestR return nullptr; if (qtSettings->useXMLOutput) - return new QtTestOutputReader(fi, app, buildDirectory(), QtTestOutputReader::XML); + return new QtTestOutputReader(fi, app, buildDirectory(), projectFile(), QtTestOutputReader::XML); else - return new QtTestOutputReader(fi, app, buildDirectory(), QtTestOutputReader::PlainText); + return new QtTestOutputReader(fi, app, buildDirectory(), projectFile(), QtTestOutputReader::PlainText); } QStringList QtTestConfiguration::argumentsForTestRunner(QStringList *omitted) const diff --git a/src/plugins/autotest/qtest/qttestoutputreader.cpp b/src/plugins/autotest/qtest/qttestoutputreader.cpp index d1999bba39..dcbcc1215c 100644 --- a/src/plugins/autotest/qtest/qttestoutputreader.cpp +++ b/src/plugins/autotest/qtest/qttestoutputreader.cpp @@ -25,6 +25,7 @@ #include "qttestoutputreader.h" #include "qttestresult.h" +#include "../testtreeitem.h" #include <utils/qtcassert.h> @@ -130,9 +131,10 @@ static QString constructSourceFilePath(const QString &path, const QString &fileP QtTestOutputReader::QtTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, QProcess *testApplication, const QString &buildDirectory, - OutputMode mode) + const QString &projectFile, OutputMode mode) : TestOutputReader(futureInterface, testApplication, buildDirectory) , m_executable(testApplication ? testApplication->program() : QString()) + , m_projectFile(projectFile) , m_mode(mode) { } @@ -269,12 +271,7 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine) } else if (currentTag == QStringLiteral("TestCase")) { sendFinishMessage(false); } else if (validEndTags.contains(currentTag.toString())) { - QtTestResult *testResult = createDefaultResult(); - testResult->setResult(m_result); - testResult->setFileName(m_file); - testResult->setLine(m_lineNumber); - testResult->setDescription(m_description); - m_futureInterface.reportResult(TestResultPtr(testResult)); + sendCompleteInformation(); if (currentTag == QStringLiteral("Incident")) m_dataTag.clear(); } @@ -420,7 +417,7 @@ void QtTestOutputReader::processSummaryFinishOutput() QtTestResult *QtTestOutputReader::createDefaultResult() const { - QtTestResult *result = new QtTestResult(m_executable, m_className); + QtTestResult *result = new QtTestResult(m_executable, m_projectFile, m_className); result->setFunctionName(m_testCase); result->setDataTag(m_dataTag); return result; @@ -430,18 +427,27 @@ void QtTestOutputReader::sendCompleteInformation() { TestResultPtr testResult = TestResultPtr(createDefaultResult()); testResult->setResult(m_result); - testResult->setFileName(m_file); - testResult->setLine(m_lineNumber); + + if (m_lineNumber) { + testResult->setFileName(m_file); + testResult->setLine(m_lineNumber); + } else { + const TestTreeItem *testItem = testResult->findTestTreeItem(); + if (testItem && testItem->line()) { + testResult->setFileName(testItem->filePath()); + testResult->setLine(static_cast<int>(testItem->line())); + } + } testResult->setDescription(m_description); - m_futureInterface.reportResult(testResult); + reportResult(testResult); } void QtTestOutputReader::sendMessageCurrentTest() { - TestResultPtr testResult = TestResultPtr(new QtTestResult); + TestResultPtr testResult = TestResultPtr(new QtTestResult(m_projectFile)); testResult->setResult(Result::MessageCurrentTest); testResult->setDescription(tr("Entering test function %1::%2").arg(m_className, m_testCase)); - m_futureInterface.reportResult(testResult); + reportResult(testResult); } void QtTestOutputReader::sendStartMessage(bool isFunction) @@ -450,7 +456,12 @@ void QtTestOutputReader::sendStartMessage(bool isFunction) testResult->setResult(Result::MessageTestCaseStart); testResult->setDescription(isFunction ? tr("Executing test function %1").arg(m_testCase) : tr("Executing test case %1").arg(m_className)); - m_futureInterface.reportResult(testResult); + const TestTreeItem *testItem = testResult->findTestTreeItem(); + if (testItem && testItem->line()) { + testResult->setFileName(testItem->filePath()); + testResult->setLine(static_cast<int>(testItem->line())); + } + reportResult(testResult); } void QtTestOutputReader::sendFinishMessage(bool isFunction) @@ -464,7 +475,7 @@ void QtTestOutputReader::sendFinishMessage(bool isFunction) testResult->setDescription(isFunction ? tr("Test function finished.") : tr("Test finished.")); } - m_futureInterface.reportResult(testResult); + reportResult(testResult); } // TODO factor out tr() strings to avoid duplication (see XML processing of Characters) @@ -473,15 +484,15 @@ void QtTestOutputReader::handleAndSendConfigMessage(const QRegExp &config) QtTestResult *testResult = createDefaultResult(); testResult->setResult(Result::MessageInternal); testResult->setDescription(tr("Qt version: %1").arg(config.cap(3))); - m_futureInterface.reportResult(TestResultPtr(testResult)); + reportResult(TestResultPtr(testResult)); testResult = createDefaultResult(); testResult->setResult(Result::MessageInternal); testResult->setDescription(tr("Qt build: %1").arg(config.cap(2))); - m_futureInterface.reportResult(TestResultPtr(testResult)); + reportResult(TestResultPtr(testResult)); testResult = createDefaultResult(); testResult->setResult(Result::MessageInternal); testResult->setDescription(tr("QTest version: %1").arg(config.cap(1))); - m_futureInterface.reportResult(TestResultPtr(testResult)); + reportResult(TestResultPtr(testResult)); } } // namespace Internal diff --git a/src/plugins/autotest/qtest/qttestoutputreader.h b/src/plugins/autotest/qtest/qttestoutputreader.h index 75f0b9a42e..f5aafc467d 100644 --- a/src/plugins/autotest/qtest/qttestoutputreader.h +++ b/src/plugins/autotest/qtest/qttestoutputreader.h @@ -48,7 +48,7 @@ public: QtTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, QProcess *testApplication, const QString &buildDirectory, - OutputMode mode); + const QString &projectFile, OutputMode mode); protected: void processOutput(const QByteArray &outputLine) override; @@ -79,6 +79,7 @@ private: CDATAMode m_cdataMode = None; QString m_executable; + QString m_projectFile; QString m_className; QString m_testCase; QString m_formerTestCase; diff --git a/src/plugins/autotest/qtest/qttestresult.cpp b/src/plugins/autotest/qtest/qttestresult.cpp index 68c9f2bf3f..64d29f08fa 100644 --- a/src/plugins/autotest/qtest/qttestresult.cpp +++ b/src/plugins/autotest/qtest/qttestresult.cpp @@ -24,19 +24,21 @@ ****************************************************************************/ #include "qttestresult.h" +#include "../testtreemodel.h" #include <utils/qtcassert.h> namespace Autotest { namespace Internal { -QtTestResult::QtTestResult(const QString &className) - : TestResult(className) +QtTestResult::QtTestResult(const QString &projectFile, const QString &className) + : TestResult(className), m_projectFile(projectFile) { } -QtTestResult::QtTestResult(const QString &executable, const QString &className) - : TestResult(executable, className) +QtTestResult::QtTestResult(const QString &executable, const QString &projectFile, + const QString &className) + : TestResult(executable, className), m_projectFile(projectFile) { } @@ -106,20 +108,96 @@ bool QtTestResult::isIntermediateFor(const TestResult *other) const QTC_ASSERT(other, return false); const QtTestResult *qtOther = static_cast<const QtTestResult *>(other); return m_dataTag == qtOther->m_dataTag && m_function == qtOther->m_function - && name() == qtOther->name() && executable() == qtOther->executable(); + && name() == qtOther->name() && executable() == qtOther->executable() + && m_projectFile == qtOther->m_projectFile; } TestResult *QtTestResult::createIntermediateResultFor(const TestResult *other) { QTC_ASSERT(other, return nullptr); const QtTestResult *qtOther = static_cast<const QtTestResult *>(other); - QtTestResult *intermediate = new QtTestResult(qtOther->executable(), qtOther->name()); + QtTestResult *intermediate = new QtTestResult(qtOther->executable(), qtOther->m_projectFile, qtOther->name()); intermediate->m_function = qtOther->m_function; intermediate->m_dataTag = qtOther->m_dataTag; // intermediates will be needed only for data tags intermediate->setDescription("Data tag: " + qtOther->m_dataTag); + const auto correspondingItem = intermediate->findTestTreeItem(); + if (correspondingItem && correspondingItem->line()) { + intermediate->setFileName(correspondingItem->filePath()); + intermediate->setLine(static_cast<int>(correspondingItem->line())); + } return intermediate; } +const TestTreeItem *QtTestResult::findTestTreeItem() const +{ + const auto item = TestTreeModel::instance()->findNonRootItem([this](const Utils::TreeItem *item) { + const TestTreeItem *treeItem = static_cast<const TestTreeItem *>(item); + return matches(treeItem); + }); + return static_cast<const TestTreeItem *>(item); +} + +bool QtTestResult::matches(const TestTreeItem *item) const +{ + QTC_ASSERT(item, return false); + TestTreeItem *parentItem = item->parentItem(); + QTC_ASSERT(parentItem, return false); + + TestTreeItem::Type type = item->type(); + switch (type) { + case TestTreeItem::TestCase: + if (!isTestCase()) + return false; + if (item->proFile() != m_projectFile) + return false; + return matchesTestCase(item); + case TestTreeItem::TestFunctionOrSet: + case TestTreeItem::TestSpecialFunction: + if (!isTestFunction()) + return false; + if (parentItem->proFile() != m_projectFile) + return false; + return matchesTestFunction(item); + case TestTreeItem::TestDataTag: { + if (!isDataTag()) + return false; + TestTreeItem *grandParentItem = parentItem->parentItem(); + QTC_ASSERT(grandParentItem, return false); + if (grandParentItem->proFile() != m_projectFile) + return false; + return matchesTestFunction(item); + } + default: + break; + } + + return false; +} + +bool QtTestResult::matchesTestCase(const TestTreeItem *item) const +{ + // FIXME this will never work for Quick Tests + if (item->name() == name()) + return true; + return false; +} + +bool QtTestResult::matchesTestFunction(const TestTreeItem *item) const +{ + TestTreeItem *parentItem = item->parentItem(); + TestTreeItem::Type type = item->type(); + if (m_function.contains("::")) { // Quick tests have slightly different layout // BAD/WRONG! + const QStringList tmp = m_function.split("::"); + QTC_ASSERT(tmp.size() == 2, return false); + return item->name() == tmp.last() && parentItem->name() == tmp.first(); + } + if (type == TestTreeItem::TestDataTag) { + TestTreeItem *grandParentItem = parentItem->parentItem(); + return parentItem->name() == m_function && grandParentItem->name() == name(); + } + return item->name() == m_function && parentItem->name() == name(); +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/qtest/qttestresult.h b/src/plugins/autotest/qtest/qttestresult.h index c7c9e8ae2a..f26de9a621 100644 --- a/src/plugins/autotest/qtest/qttestresult.h +++ b/src/plugins/autotest/qtest/qttestresult.h @@ -33,8 +33,8 @@ namespace Internal { class QtTestResult : public TestResult { public: - explicit QtTestResult(const QString &className = QString()); - QtTestResult(const QString &executable, const QString &className); + explicit QtTestResult(const QString &projectFile, const QString &className = QString()); + QtTestResult(const QString &executable, const QString &projectFile, const QString &className); const QString outputString(bool selected) const override; void setFunctionName(const QString &functionName) { m_function = functionName; } @@ -43,13 +43,19 @@ public: bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const override; bool isIntermediateFor(const TestResult *other) const override; TestResult *createIntermediateResultFor(const TestResult *other) override; + const TestTreeItem *findTestTreeItem() const override; private: bool isTestCase() const { return m_function.isEmpty() && m_dataTag.isEmpty(); } bool isTestFunction() const { return !m_function.isEmpty() && m_dataTag.isEmpty(); } bool isDataTag() const { return !m_function.isEmpty() && !m_dataTag.isEmpty(); } + bool matches(const TestTreeItem *item) const; + bool matchesTestCase(const TestTreeItem *item) const; + bool matchesTestFunction(const TestTreeItem *item) const; + QString m_function; QString m_dataTag; + QString m_projectFile; }; } // namespace Internal diff --git a/src/plugins/autotest/quick/quicktestconfiguration.cpp b/src/plugins/autotest/quick/quicktestconfiguration.cpp index 88920e0352..827b350cfe 100644 --- a/src/plugins/autotest/quick/quicktestconfiguration.cpp +++ b/src/plugins/autotest/quick/quicktestconfiguration.cpp @@ -45,9 +45,9 @@ TestOutputReader *QuickTestConfiguration::outputReader(const QFutureInterface<Te if (qtSettings.isNull()) return nullptr; if (qtSettings->useXMLOutput) - return new QtTestOutputReader(fi, app, buildDirectory(), QtTestOutputReader::XML); + return new QtTestOutputReader(fi, app, buildDirectory(), projectFile(), QtTestOutputReader::XML); else - return new QtTestOutputReader(fi, app, buildDirectory(), QtTestOutputReader::PlainText); + return new QtTestOutputReader(fi, app, buildDirectory(), projectFile(), QtTestOutputReader::PlainText); } QStringList QuickTestConfiguration::argumentsForTestRunner(QStringList *omitted) const diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp index b4af50e8a9..34c8ef1813 100644 --- a/src/plugins/autotest/testconfiguration.cpp +++ b/src/plugins/autotest/testconfiguration.cpp @@ -76,6 +76,10 @@ void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguratio TestRunMode runMode) { QTC_ASSERT(rc, return); + if (hasExecutable()) { + qCDebug(LOG) << "Executable has been set already - not completing configuration again."; + return; + } Project *project = SessionManager::startupProject(); if (!project) return; diff --git a/src/plugins/autotest/testoutputreader.cpp b/src/plugins/autotest/testoutputreader.cpp index fea9237717..b17af8ec73 100644 --- a/src/plugins/autotest/testoutputreader.cpp +++ b/src/plugins/autotest/testoutputreader.cpp @@ -66,5 +66,11 @@ void TestOutputReader::processStdError(const QByteArray &output) qWarning() << "AutoTest.Run: Ignored plain output:" << output; } +void TestOutputReader::reportResult(const TestResultPtr &result) +{ + m_futureInterface.reportResult(result); + m_hadValidOutput = true; +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/testoutputreader.h b/src/plugins/autotest/testoutputreader.h index ff04d8f4ce..c9fe9cd19a 100644 --- a/src/plugins/autotest/testoutputreader.h +++ b/src/plugins/autotest/testoutputreader.h @@ -44,13 +44,17 @@ public: virtual void processOutput(const QByteArray &outputLine) = 0; virtual void processStdError(const QByteArray &output); + bool hadValidOutput() const { return m_hadValidOutput; } signals: void newOutputAvailable(const QByteArray &output); protected: + void reportResult(const TestResultPtr &result); QFutureInterface<TestResultPtr> m_futureInterface; QProcess *m_testApplication; // not owned QString m_buildDir; +private: + bool m_hadValidOutput = false; }; } // namespace Internal diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp index c3317fdfe9..9f2f8431ea 100644 --- a/src/plugins/autotest/testresultspane.cpp +++ b/src/plugins/autotest/testresultspane.cpp @@ -583,15 +583,16 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos) connect(action, &QAction::triggered, this, &TestResultsPane::onSaveWholeTriggered); menu.addAction(action); + const auto correlatingItem = clicked ? clicked->findTestTreeItem() : nullptr; action = new QAction(tr("Run This Test"), &menu); - action->setEnabled(clicked && clicked->findTestTreeItem()); + action->setEnabled(correlatingItem && correlatingItem->canProvideTestConfiguration()); connect(action, &QAction::triggered, this, [this, clicked] { onRunThisTestTriggered(TestRunMode::Run, clicked); }); menu.addAction(action); action = new QAction(tr("Debug This Test"), &menu); - action->setEnabled(clicked && clicked->findTestTreeItem()); + action->setEnabled(correlatingItem && correlatingItem->canProvideDebugConfiguration()); connect(action, &QAction::triggered, this, [this, clicked] { onRunThisTestTriggered(TestRunMode::Debug, clicked); }); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 81bc2c7451..4b95da0812 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -257,6 +257,11 @@ static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface, TestRunner::tr("Test for project \"%1\" crashed.") .arg(testConfiguration->displayName()) + processInformation(testProcess) + rcInfo(testConfiguration)))); + } else if (!outputReader->hadValidOutput()) { + futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal, + TestRunner::tr("Test for project \"%1\" did not produce any expected output.") + .arg(testConfiguration->displayName()) + processInformation(testProcess) + + rcInfo(testConfiguration)))); } if (canceledByTimeout) { @@ -362,12 +367,24 @@ static bool askUserForRunConfiguration(TestConfiguration *config) void TestRunner::runTests() { + QList<TestConfiguration *> toBeRemoved; for (TestConfiguration *config : m_selectedTests) { config->completeTestInformation(TestRunMode::Run); if (!config->hasExecutable()) - if (askUserForRunConfiguration(config)) - config->completeTestInformation(config->originalRunConfiguration(), TestRunMode::Run); + if (!askUserForRunConfiguration(config)) + toBeRemoved.append(config); + } + for (TestConfiguration *config : toBeRemoved) + m_selectedTests.removeOne(config); + qDeleteAll(toBeRemoved); + toBeRemoved.clear(); + if (m_selectedTests.isEmpty()) { + emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, + tr("No test cases left for execution. Canceling test run.")))); + onFinished(); + return; } + QFuture<TestResultPtr> future = Utils::runAsync(&performTestRun, m_selectedTests, *AutotestPlugin::instance()->settings()); m_futureWatcher.setFuture(future); diff --git a/src/plugins/baremetal/baremetalrunconfiguration.cpp b/src/plugins/baremetal/baremetalrunconfiguration.cpp index d950f6cc34..c0155f7bf7 100644 --- a/src/plugins/baremetal/baremetalrunconfiguration.cpp +++ b/src/plugins/baremetal/baremetalrunconfiguration.cpp @@ -112,17 +112,15 @@ QString BareMetalRunConfiguration::defaultDisplayName() { if (!m_projectFilePath.isEmpty()) //: %1 is the name of the project run via hardware debugger - return tr("%1 (via GDB server or hardware debugger)").arg(QFileInfo(m_projectFilePath).completeBaseName()); + return tr("%1 (via GDB server or hardware debugger)").arg(QFileInfo(m_projectFilePath).fileName()); //: Bare Metal run configuration default run name return tr("Run on GDB server or hardware debugger"); } QString BareMetalRunConfiguration::localExecutableFilePath() const { - const QString targetName = QFileInfo(m_projectFilePath).completeBaseName(); - - return target()->applicationTargets() - .targetFilePath(FileName::fromString(targetName).toString()).toString(); + const QString targetName = QFileInfo(m_projectFilePath).fileName(); + return target()->applicationTargets().targetFilePath(targetName).toString(); } QString BareMetalRunConfiguration::arguments() const @@ -149,7 +147,7 @@ QString BareMetalRunConfiguration::buildSystemTarget() const { const BuildTargetInfoList targets = target()->applicationTargets(); const Utils::FileName projectFilePath = Utils::FileName::fromString(QFileInfo(m_projectFilePath).path()); - const QString targetName = QFileInfo(m_projectFilePath).completeBaseName(); + const QString targetName = QFileInfo(m_projectFilePath).fileName(); auto bst = std::find_if(targets.list.constBegin(), targets.list.constEnd(), [&projectFilePath,&targetName](const BuildTargetInfo &bti) { return bti.projectFilePath == projectFilePath && bti.targetName == targetName; }); return (bst == targets.list.constEnd()) ? QString() : bst->targetName; diff --git a/src/plugins/baremetal/baremetalrunconfigurationfactory.cpp b/src/plugins/baremetal/baremetalrunconfigurationfactory.cpp index 31d00c7f39..4c0c34596a 100644 --- a/src/plugins/baremetal/baremetalrunconfigurationfactory.cpp +++ b/src/plugins/baremetal/baremetalrunconfigurationfactory.cpp @@ -60,7 +60,7 @@ bool BareMetalRunConfigurationFactory::canCreate(Target *parent, Core::Id id) co { if (!canHandle(parent)) return false; - const QString targetName = QFileInfo(pathFromId(id)).completeBaseName(); + const QString targetName = QFileInfo(pathFromId(id)).fileName(); return id == BareMetalCustomRunConfiguration::runConfigId() || !parent->applicationTargets().targetFilePath(targetName).isEmpty(); } @@ -100,7 +100,7 @@ QString BareMetalRunConfigurationFactory::displayNameForId(Core::Id id) const if (id == BareMetalCustomRunConfiguration::runConfigId()) return BareMetalCustomRunConfiguration::runConfigDefaultDisplayName(); return tr("%1 (on GDB server or hardware debugger)") - .arg(QFileInfo(pathFromId(id)).completeBaseName()); + .arg(QFileInfo(pathFromId(id)).fileName()); } RunConfiguration *BareMetalRunConfigurationFactory::doCreate(Target *parent, Core::Id id) diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp new file mode 100644 index 0000000000..fc5603b0c0 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp @@ -0,0 +1,581 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangbackendcommunicator.h" + +#include "clangbackendlogging.h" +#include "clangcompletionassistprocessor.h" +#include "clangmodelmanagersupport.h" +#include "clangutils.h" + +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/icore.h> +#include <coreplugin/messagemanager.h> + +#include <cpptools/abstracteditorsupport.h> +#include <cpptools/baseeditordocumentprocessor.h> +#include <cpptools/cppmodelmanager.h> +#include <cpptools/editordocumenthandle.h> +#include <cpptools/projectinfo.h> +#include <cpptools/cpptoolsbridge.h> + +#include <texteditor/codeassist/functionhintproposal.h> +#include <texteditor/codeassist/iassistprocessor.h> +#include <texteditor/texteditor.h> + +#include <clangsupport/filecontainer.h> +#include <clangsupport/clangcodemodelservermessages.h> + +#include <utils/qtcassert.h> + +#include <QDateTime> +#include <QDir> +#include <QTextBlock> + +using namespace CPlusPlus; +using namespace ClangBackEnd; +using namespace TextEditor; + +enum { backEndStartTimeOutInMs = 10000 }; + +static QString backendProcessPath() +{ + return Core::ICore::libexecPath() + + QStringLiteral("/clangbackend") + + QStringLiteral(QTC_HOST_EXE_SUFFIX); +} + +namespace ClangCodeModel { +namespace Internal { + +class DummyBackendSender : public BackendSender +{ +public: + DummyBackendSender() : BackendSender(nullptr) {} + + void end() override {} + void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &) override {} + void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &) override {} + void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &) override {} + void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &) override {} + void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &) override {} + void registerUnsavedFilesForEditor(const RegisterUnsavedFilesForEditorMessage &) override {} + void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &) override {} + void completeCode(const CompleteCodeMessage &) override {} + void requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &) override {} + void requestReferences(const RequestReferencesMessage &) override {} + void requestFollowSymbol(const RequestFollowSymbolMessage &) override {} + void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &) override {} +}; + + +BackendCommunicator::BackendCommunicator() + : m_connection(&m_receiver) + , m_sender(new DummyBackendSender()) +{ + m_backendStartTimeOut.setSingleShot(true); + connect(&m_backendStartTimeOut, &QTimer::timeout, + this, &BackendCommunicator::logStartTimeOut); + + m_receiver.setAliveHandler([this]() { m_connection.resetProcessAliveTimer(); }); + + connect(Core::EditorManager::instance(), &Core::EditorManager::editorAboutToClose, + this, &BackendCommunicator::onEditorAboutToClose); + connect(Core::ICore::instance(), &Core::ICore::coreAboutToClose, + this, &BackendCommunicator::setupDummySender); + + initializeBackend(); +} + +BackendCommunicator::~BackendCommunicator() +{ + disconnect(&m_connection, 0, this, 0); +} + +void BackendCommunicator::initializeBackend() +{ + const QString clangBackEndProcessPath = backendProcessPath(); + if (!QFileInfo(clangBackEndProcessPath).exists()) { + logExecutableDoesNotExist(); + return; + } + qCDebug(ipcLog) << "Starting" << clangBackEndProcessPath; + + m_connection.setProcessAliveTimerInterval(30 * 1000); + m_connection.setProcessPath(clangBackEndProcessPath); + + connect(&m_connection, &ConnectionClient::connectedToLocalSocket, + this, &BackendCommunicator::onConnectedToBackend); + connect(&m_connection, &ConnectionClient::disconnectedFromLocalSocket, + this, &BackendCommunicator::setupDummySender); + + m_connection.startProcessAndConnectToServerAsynchronously(); + m_backendStartTimeOut.start(backEndStartTimeOutInMs); +} + +static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart) +{ + const QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart, + CppTools::ProjectFile::Unsupported); // No language option + + return options; +} + +static ProjectPartContainer toProjectPartContainer( + const CppTools::ProjectPart::Ptr &projectPart) +{ + const QStringList options = projectPartOptions(projectPart); + + return ProjectPartContainer(projectPart->id(), Utf8StringVector(options)); +} + +static QVector<ProjectPartContainer> toProjectPartContainers( + const QVector<CppTools::ProjectPart::Ptr> projectParts) +{ + QVector<ProjectPartContainer> projectPartContainers; + projectPartContainers.reserve(projectParts.size()); + + foreach (const CppTools::ProjectPart::Ptr &projectPart, projectParts) + projectPartContainers << toProjectPartContainer(projectPart); + + return projectPartContainers; +} + +void BackendCommunicator::registerFallbackProjectPart() +{ + const auto projectPart = CppTools::CppModelManager::instance()->fallbackProjectPart(); + const auto projectPartContainer = toProjectPartContainer(projectPart); + + registerProjectPartsForEditor({projectPartContainer}); +} + +namespace { +Utf8String currentCppEditorDocumentFilePath() +{ + Utf8String currentCppEditorDocumentFilePath; + + const auto currentEditor = Core::EditorManager::currentEditor(); + if (currentEditor && CppTools::CppModelManager::isCppEditor(currentEditor)) { + const auto currentDocument = currentEditor->document(); + if (currentDocument) + currentCppEditorDocumentFilePath = currentDocument->filePath().toString(); + } + + return currentCppEditorDocumentFilePath; +} + +void removeDuplicates(Utf8StringVector &visibleEditorDocumentsFilePaths) +{ + std::sort(visibleEditorDocumentsFilePaths.begin(), + visibleEditorDocumentsFilePaths.end()); + const auto end = std::unique(visibleEditorDocumentsFilePaths.begin(), + visibleEditorDocumentsFilePaths.end()); + visibleEditorDocumentsFilePaths.erase(end, + visibleEditorDocumentsFilePaths.end()); +} + +void removeNonCppEditors(QList<Core::IEditor*> &visibleEditors) +{ + const auto isNotCppEditor = [] (Core::IEditor *editor) { + return !CppTools::CppModelManager::isCppEditor(editor); + }; + + const auto end = std::remove_if(visibleEditors.begin(), + visibleEditors.end(), + isNotCppEditor); + + visibleEditors.erase(end, visibleEditors.end()); +} + +Utf8StringVector visibleCppEditorDocumentsFilePaths() +{ + auto visibleEditors = CppTools::CppToolsBridge::visibleEditors(); + + removeNonCppEditors(visibleEditors); + + Utf8StringVector visibleCppEditorDocumentsFilePaths; + visibleCppEditorDocumentsFilePaths.reserve(visibleEditors.size()); + + const auto editorFilePaths = [] (Core::IEditor *editor) { + return Utf8String(editor->document()->filePath().toString()); + }; + + std::transform(visibleEditors.begin(), + visibleEditors.end(), + std::back_inserter(visibleCppEditorDocumentsFilePaths), + editorFilePaths); + + removeDuplicates(visibleCppEditorDocumentsFilePaths); + + return visibleCppEditorDocumentsFilePaths; +} + +} + +void BackendCommunicator::updateTranslationUnitVisiblity() +{ + updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths()); +} + +bool BackendCommunicator::isNotWaitingForCompletion() const +{ + return !m_receiver.isExpectingCodeCompletedMessage(); +} + +void BackendCommunicator::updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, + const Utf8StringVector &visibleEditorsFilePaths) +{ + const UpdateVisibleTranslationUnitsMessage message(currentEditorFilePath, visibleEditorsFilePaths); + m_sender->updateVisibleTranslationUnits(message); +} + +void BackendCommunicator::registerCurrentProjectParts() +{ + using namespace CppTools; + + const QList<ProjectInfo> projectInfos = CppModelManager::instance()->projectInfos(); + foreach (const ProjectInfo &projectInfo, projectInfos) + registerProjectsParts(projectInfo.projectParts()); +} + +void BackendCommunicator::restoreCppEditorDocuments() +{ + resetCppEditorDocumentProcessors(); + registerVisibleCppEditorDocumentAndMarkInvisibleDirty(); +} + +void BackendCommunicator::resetCppEditorDocumentProcessors() +{ + using namespace CppTools; + + const auto cppEditorDocuments = CppModelManager::instance()->cppEditorDocuments(); + foreach (CppEditorDocumentHandle *cppEditorDocument, cppEditorDocuments) + cppEditorDocument->resetProcessor(); +} + +void BackendCommunicator::registerVisibleCppEditorDocumentAndMarkInvisibleDirty() +{ + CppTools::CppModelManager::instance()->updateCppEditorDocuments(); +} + +void BackendCommunicator::registerCurrentCodeModelUiHeaders() +{ + using namespace CppTools; + + const auto editorSupports = CppModelManager::instance()->abstractEditorSupports(); + foreach (const AbstractEditorSupport *es, editorSupports) { + const QString mappedPath + = ModelManagerSupportClang::instance()->dummyUiHeaderOnDiskPath(es->fileName()); + updateUnsavedFile(mappedPath, es->contents(), es->revision()); + } +} + +void BackendCommunicator::registerProjectsParts(const QVector<CppTools::ProjectPart::Ptr> projectParts) +{ + const auto projectPartContainers = toProjectPartContainers(projectParts); + registerProjectPartsForEditor(projectPartContainers); +} + +void BackendCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath) +{ + const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); + + updateTranslationUnit(filePath, document->contents(), document->revision()); +} + +void BackendCommunicator::updateUnsavedFileFromCppEditorDocument(const QString &filePath) +{ + const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); + + updateUnsavedFile(filePath, document->contents(), document->revision()); +} + +void BackendCommunicator::updateTranslationUnit(const QString &filePath, + const QByteArray &contents, + uint documentRevision) +{ + const bool hasUnsavedContent = true; + + updateTranslationUnitsForEditor({{filePath, + Utf8String(), + Utf8String::fromByteArray(contents), + hasUnsavedContent, + documentRevision}}); +} + +void BackendCommunicator::updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision) +{ + const bool hasUnsavedContent = true; + + // TODO: Send new only if changed + registerUnsavedFilesForEditor({{filePath, + Utf8String(), + Utf8String::fromByteArray(contents), + hasUnsavedContent, + documentRevision}}); +} + +static bool documentHasChanged(const QString &filePath, uint revision) +{ + if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) + return document->sendTracker().shouldSendRevision(revision); + + return true; +} + +static void setLastSentDocumentRevision(const QString &filePath, uint revision) +{ + if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) + document->sendTracker().setLastSentRevision(int(revision)); +} + +void BackendCommunicator::updateTranslationUnitWithRevisionCheck(const FileContainer &fileContainer) +{ + if (documentHasChanged(fileContainer.filePath(), fileContainer.documentRevision())) { + updateTranslationUnitsForEditor({fileContainer}); + setLastSentDocumentRevision(fileContainer.filePath(), + fileContainer.documentRevision()); + } +} + +void BackendCommunicator::requestDocumentAnnotations(const FileContainer &fileContainer) +{ + const RequestDocumentAnnotationsMessage message(fileContainer); + m_sender->requestDocumentAnnotations(message); +} + +QFuture<CppTools::CursorInfo> BackendCommunicator::requestReferences( + const FileContainer &fileContainer, + quint32 line, + quint32 column, + QTextDocument *textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses) +{ + const RequestReferencesMessage message(fileContainer, line, column); + m_sender->requestReferences(message); + + return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument, + localUses); +} + +QFuture<CppTools::SymbolInfo> BackendCommunicator::requestFollowSymbol( + const FileContainer &curFileContainer, + const QVector<Utf8String> &dependentFiles, + quint32 line, + quint32 column) +{ + const RequestFollowSymbolMessage message(curFileContainer, + dependentFiles, + line, + column); + m_sender->requestFollowSymbol(message); + + return m_receiver.addExpectedRequestFollowSymbolMessage(message.ticketNumber()); +} + +void BackendCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document) +{ + const auto textDocument = qobject_cast<TextDocument*>(document); + const auto filePath = textDocument->filePath().toString(); + const QString projectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); + + updateTranslationUnitWithRevisionCheck(FileContainer(filePath, + projectPartId, + Utf8StringVector(), + textDocument->document()->revision())); +} + +void BackendCommunicator::updateChangeContentStartPosition(const QString &filePath, int position) +{ + if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) + document->sendTracker().applyContentChange(position); +} + +void BackendCommunicator::updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document) +{ + QTC_ASSERT(document, return); + if (Core::EditorManager::currentDocument() != document) + updateTranslationUnit(document); +} + +void BackendCommunicator::updateTranslationUnit(Core::IDocument *document) +{ + updateTranslationUnitFromCppEditorDocument(document->filePath().toString()); +} + +void BackendCommunicator::updateUnsavedFile(Core::IDocument *document) +{ + QTC_ASSERT(document, return); + + updateUnsavedFileFromCppEditorDocument(document->filePath().toString()); +} + +void BackendCommunicator::onConnectedToBackend() +{ + m_backendStartTimeOut.stop(); + + ++m_connectedCount; + if (m_connectedCount > 1) + logRestartedDueToUnexpectedFinish(); + + m_receiver.reset(); + m_sender.reset(new BackendSender(&m_connection)); + + initializeBackendWithCurrentData(); +} + +void BackendCommunicator::onEditorAboutToClose(Core::IEditor *editor) +{ + if (auto *textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor)) + m_receiver.deleteProcessorsOfEditorWidget(textEditor->editorWidget()); +} + +void BackendCommunicator::setupDummySender() +{ + m_sender.reset(new DummyBackendSender); +} + +void BackendCommunicator::logExecutableDoesNotExist() +{ + const QString msg + = tr("Clang Code Model: Error: " + "The clangbackend executable \"%1\" does not exist.") + .arg(QDir::toNativeSeparators(backendProcessPath())); + + logError(msg); +} + +void BackendCommunicator::logStartTimeOut() +{ + const QString msg + = tr("Clang Code Model: Error: " + "The clangbackend executable \"%1\" could not be started (timeout after %2ms).") + .arg(QDir::toNativeSeparators(backendProcessPath())) + .arg(backEndStartTimeOutInMs); + + logError(msg); +} + +void BackendCommunicator::logRestartedDueToUnexpectedFinish() +{ + const QString msg + = tr("Clang Code Model: Error: " + "The clangbackend process has finished unexpectedly and was restarted."); + + logError(msg); +} + +void BackendCommunicator::logError(const QString &text) +{ + const QString textWithTimestamp = QDateTime::currentDateTime().toString(Qt::ISODate) + + ' ' + text; + Core::MessageManager::write(textWithTimestamp, Core::MessageManager::Flash); + qWarning("%s", qPrintable(textWithTimestamp)); +} + +void BackendCommunicator::initializeBackendWithCurrentData() +{ + registerFallbackProjectPart(); + registerCurrentProjectParts(); + registerCurrentCodeModelUiHeaders(); + restoreCppEditorDocuments(); + updateTranslationUnitVisiblity(); + + emit backendReinitialized(); +} + +BackendSender *BackendCommunicator::setBackendSender(BackendSender *sender) +{ + BackendSender *previousSender = m_sender.take(); + m_sender.reset(sender); + return previousSender; +} + +void BackendCommunicator::killBackendProcess() +{ + m_connection.processForTestOnly()->kill(); +} + +void BackendCommunicator::registerTranslationUnitsForEditor(const FileContainers &fileContainers) +{ + const RegisterTranslationUnitForEditorMessage message(fileContainers, + currentCppEditorDocumentFilePath(), + visibleCppEditorDocumentsFilePaths()); + m_sender->registerTranslationUnitsForEditor(message); +} + +void BackendCommunicator::updateTranslationUnitsForEditor(const FileContainers &fileContainers) +{ + const UpdateTranslationUnitsForEditorMessage message(fileContainers); + m_sender->updateTranslationUnitsForEditor(message); +} + +void BackendCommunicator::unregisterTranslationUnitsForEditor(const FileContainers &fileContainers) +{ + const UnregisterTranslationUnitsForEditorMessage message(fileContainers); + m_sender->unregisterTranslationUnitsForEditor(message); +} + +void BackendCommunicator::registerProjectPartsForEditor( + const ProjectPartContainers &projectPartContainers) +{ + const RegisterProjectPartsForEditorMessage message(projectPartContainers); + m_sender->registerProjectPartsForEditor(message); +} + +void BackendCommunicator::unregisterProjectPartsForEditor(const QStringList &projectPartIds) +{ + const UnregisterProjectPartsForEditorMessage message((Utf8StringVector(projectPartIds))); + m_sender->unregisterProjectPartsForEditor(message); +} + +void BackendCommunicator::registerUnsavedFilesForEditor(const FileContainers &fileContainers) +{ + const RegisterUnsavedFilesForEditorMessage message(fileContainers); + m_sender->registerUnsavedFilesForEditor(message); +} + +void BackendCommunicator::unregisterUnsavedFilesForEditor(const FileContainers &fileContainers) +{ + const UnregisterUnsavedFilesForEditorMessage message(fileContainers); + m_sender->unregisterUnsavedFilesForEditor(message); +} + +void BackendCommunicator::completeCode(ClangCompletionAssistProcessor *assistProcessor, + const QString &filePath, + quint32 line, + quint32 column, + const QString &projectFilePath, + qint32 funcNameStartLine, + qint32 funcNameStartColumn) +{ + const CompleteCodeMessage message(filePath, line, column, projectFilePath, funcNameStartLine, + funcNameStartColumn); + m_sender->completeCode(message); + m_receiver.addExpectedCodeCompletedMessage(message.ticketNumber(), assistProcessor); +} + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendcommunicator.h index 5c7eb6f922..86054e566f 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.h @@ -25,135 +25,42 @@ #pragma once +#include "clangbackendreceiver.h" +#include "clangbackendsender.h" + #include <cpptools/projectpart.h> -#include <cpptools/cppcursorinfo.h> -#include <cpptools/cppsymbolinfo.h> #include <clangsupport/clangcodemodelconnectionclient.h> #include <clangsupport/filecontainer.h> -#include <clangsupport/clangcodemodelclientinterface.h> #include <clangsupport/projectpartcontainer.h> #include <QFuture> #include <QObject> -#include <QPointer> -#include <QSharedPointer> -#include <QTextDocument> #include <QVector> - -#include <functional> +#include <QTimer> namespace Core { class IEditor; class IDocument; } -namespace ClangBackEnd { -class DocumentAnnotationsChangedMessage; -} - -namespace TextEditor { -class TextEditorWidget; -class TextDocument; -} - namespace ClangCodeModel { namespace Internal { -class ModelManagerSupportClang; - class ClangCompletionAssistProcessor; -class IpcReceiver : public ClangBackEnd::ClangCodeModelClientInterface -{ -public: - IpcReceiver(); - ~IpcReceiver(); - - using AliveHandler = std::function<void ()>; - void setAliveHandler(const AliveHandler &handler); - - void addExpectedCodeCompletedMessage(quint64 ticket, ClangCompletionAssistProcessor *processor); - void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget); - - QFuture<CppTools::CursorInfo> - addExpectedReferencesMessage(quint64 ticket, - QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses); - QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket); - bool isExpectingCodeCompletedMessage() const; - - void reset(); - -private: - void alive() override; - void echo(const ClangBackEnd::EchoMessage &message) override; - void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override; - - void documentAnnotationsChanged(const ClangBackEnd::DocumentAnnotationsChangedMessage &message) override; - void references(const ClangBackEnd::ReferencesMessage &message) override; - void followSymbol(const ClangBackEnd::FollowSymbolMessage &message) override; - -private: - AliveHandler m_aliveHandler; - QHash<quint64, ClangCompletionAssistProcessor *> m_assistProcessorsTable; - - struct ReferencesEntry { - ReferencesEntry() = default; - ReferencesEntry(QFutureInterface<CppTools::CursorInfo> futureInterface, - QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses) - : futureInterface(futureInterface) - , textDocument(textDocument) - , localUses(localUses) {} - QFutureInterface<CppTools::CursorInfo> futureInterface; - QPointer<QTextDocument> textDocument; - CppTools::SemanticInfo::LocalUseMap localUses; - }; - QHash<quint64, ReferencesEntry> m_referencesTable; - - QHash<quint64, QFutureInterface<CppTools::SymbolInfo>> m_followTable; -}; - -class IpcSender : public ClangBackEnd::ClangCodeModelServerInterface -{ -public: - IpcSender(ClangBackEnd::ClangCodeModelConnectionClient *connectionClient); - - void end() override; - void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override; - void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override; - void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override; - void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override; - void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override; - void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &message) override; - void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override; - void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; - void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) override; - void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) override; - void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) override; - void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) override; - -private: - bool isConnected() const; - -private: - ClangBackEnd::ClangCodeModelConnectionClient *m_connection = nullptr; -}; - -class IpcCommunicator : public QObject +class BackendCommunicator : public QObject { Q_OBJECT public: - using Ptr = QSharedPointer<IpcCommunicator>; using FileContainer = ClangBackEnd::FileContainer; using FileContainers = QVector<ClangBackEnd::FileContainer>; using ProjectPartContainers = QVector<ClangBackEnd::ProjectPartContainer>; public: - IpcCommunicator(); - ~IpcCommunicator(); + BackendCommunicator(); + ~BackendCommunicator(); void registerTranslationUnitsForEditor(const FileContainers &fileContainers); void updateTranslationUnitsForEditor(const FileContainers &fileContainers); @@ -199,7 +106,7 @@ public: bool isNotWaitingForCompletion() const; public: // for tests - IpcSender *setIpcSender(IpcSender *ipcSender); + BackendSender *setBackendSender(BackendSender *sender); void killBackendProcess(); signals: // for tests @@ -229,10 +136,10 @@ private: const Utf8StringVector &visibleEditorsFilePaths); private: - IpcReceiver m_ipcReceiver; + BackendReceiver m_receiver; ClangBackEnd::ClangCodeModelConnectionClient m_connection; QTimer m_backendStartTimeOut; - QScopedPointer<IpcSender> m_ipcSender; + QScopedPointer<BackendSender> m_sender; int m_connectedCount = 0; }; diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp deleted file mode 100644 index 8a953af9c3..0000000000 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ /dev/null @@ -1,927 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "clangbackendipcintegration.h" - -#include "clangcompletionassistprocessor.h" -#include "clangeditordocumentprocessor.h" -#include "clangmodelmanagersupport.h" -#include "clangutils.h" - -#include <coreplugin/editormanager/editormanager.h> -#include <coreplugin/icore.h> -#include <coreplugin/messagemanager.h> - -#include <cpptools/abstracteditorsupport.h> -#include <cpptools/baseeditordocumentprocessor.h> -#include <cpptools/cppmodelmanager.h> -#include <cpptools/cpptoolsbridge.h> -#include <cpptools/editordocumenthandle.h> -#include <cpptools/projectinfo.h> - -#include <texteditor/codeassist/functionhintproposal.h> -#include <texteditor/codeassist/iassistprocessor.h> -#include <texteditor/texteditor.h> - -#include <utils/hostosinfo.h> -#include <utils/qtcassert.h> - -#include <clangsupport/clangcodemodelservermessages.h> -#include <clangsupport/clangcodemodelclientmessages.h> -#include <clangsupport/filecontainer.h> - -#include <cplusplus/Icons.h> - -#include <QDateTime> -#include <QDir> -#include <QElapsedTimer> -#include <QLoggingCategory> -#include <QProcess> -#include <QTextBlock> - -static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.ipc") - -using namespace CPlusPlus; -using namespace ClangCodeModel; -using namespace ClangCodeModel::Internal; -using namespace ClangBackEnd; -using namespace TextEditor; - -static QString backendProcessPath() -{ - return Core::ICore::libexecPath() - + QStringLiteral("/clangbackend") - + QStringLiteral(QTC_HOST_EXE_SUFFIX); -} - -static bool printAliveMessageHelper() -{ - const bool print = qEnvironmentVariableIntValue("QTC_CLANG_FORCE_VERBOSE_ALIVE"); - if (!print) { - qCDebug(log) << "Hint: AliveMessage will not be printed. " - "Force it by setting QTC_CLANG_FORCE_VERBOSE_ALIVE=1."; - } - - return print; -} - -static bool printAliveMessage() -{ - static bool print = log().isDebugEnabled() ? printAliveMessageHelper() : false; - return print; -} - -IpcReceiver::IpcReceiver() -{ -} - -IpcReceiver::~IpcReceiver() -{ - reset(); -} - -void IpcReceiver::setAliveHandler(const IpcReceiver::AliveHandler &handler) -{ - m_aliveHandler = handler; -} - -void IpcReceiver::addExpectedCodeCompletedMessage( - quint64 ticket, - ClangCompletionAssistProcessor *processor) -{ - QTC_ASSERT(processor, return); - QTC_CHECK(!m_assistProcessorsTable.contains(ticket)); - m_assistProcessorsTable.insert(ticket, processor); -} - -void IpcReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget) -{ - QMutableHashIterator<quint64, ClangCompletionAssistProcessor *> it(m_assistProcessorsTable); - while (it.hasNext()) { - it.next(); - ClangCompletionAssistProcessor *assistProcessor = it.value(); - if (assistProcessor->textEditorWidget() == textEditorWidget) { - delete assistProcessor; - it.remove(); - } - } -} - -QFuture<CppTools::CursorInfo> IpcReceiver::addExpectedReferencesMessage( - quint64 ticket, - QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses) -{ - QTC_CHECK(textDocument); - QTC_CHECK(!m_referencesTable.contains(ticket)); - - QFutureInterface<CppTools::CursorInfo> futureInterface; - futureInterface.reportStarted(); - - const ReferencesEntry entry{futureInterface, textDocument, localUses}; - m_referencesTable.insert(ticket, entry); - - return futureInterface.future(); -} - -QFuture<CppTools::SymbolInfo> IpcReceiver::addExpectedRequestFollowSymbolMessage(quint64 ticket) -{ - QTC_CHECK(!m_followTable.contains(ticket)); - - QFutureInterface<CppTools::SymbolInfo> futureInterface; - futureInterface.reportStarted(); - - m_followTable.insert(ticket, futureInterface); - - return futureInterface.future(); -} - -bool IpcReceiver::isExpectingCodeCompletedMessage() const -{ - return !m_assistProcessorsTable.isEmpty(); -} - -void IpcReceiver::reset() -{ - // Clean up waiting assist processors - qDeleteAll(m_assistProcessorsTable.begin(), m_assistProcessorsTable.end()); - m_assistProcessorsTable.clear(); - - // Clean up futures for references - for (ReferencesEntry &entry : m_referencesTable) - entry.futureInterface.cancel(); - m_referencesTable.clear(); - for (QFutureInterface<CppTools::SymbolInfo> &futureInterface : m_followTable) - futureInterface.cancel(); - m_followTable.clear(); -} - -void IpcReceiver::alive() -{ - if (printAliveMessage()) - qCDebug(log) << "<<< AliveMessage"; - QTC_ASSERT(m_aliveHandler, return); - m_aliveHandler(); -} - -void IpcReceiver::echo(const EchoMessage &message) -{ - qCDebug(log) << "<<<" << message; -} - -void IpcReceiver::codeCompleted(const CodeCompletedMessage &message) -{ - qCDebug(log) << "<<< CodeCompletedMessage with" << message.codeCompletions().size() << "items"; - - const quint64 ticket = message.ticketNumber(); - QScopedPointer<ClangCompletionAssistProcessor> processor(m_assistProcessorsTable.take(ticket)); - if (processor) { - processor->handleAvailableCompletions(message.codeCompletions(), - message.neededCorrection()); - } -} - -void IpcReceiver::documentAnnotationsChanged(const DocumentAnnotationsChangedMessage &message) -{ - qCDebug(log) << "<<< DocumentAnnotationsChangedMessage with" - << message.diagnostics().size() << "diagnostics" - << message.highlightingMarks().size() << "highlighting marks" - << message.skippedPreprocessorRanges().size() << "skipped preprocessor ranges"; - - auto processor = ClangEditorDocumentProcessor::get(message.fileContainer().filePath()); - - if (processor) { - const QString projectPartId = message.fileContainer().projectPartId(); - const QString filePath = message.fileContainer().filePath(); - const QString documentProjectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); - if (projectPartId == documentProjectPartId) { - const quint32 documentRevision = message.fileContainer().documentRevision(); - processor->updateCodeWarnings(message.diagnostics(), - message.firstHeaderErrorDiagnostic(), - documentRevision); - processor->updateHighlighting(message.highlightingMarks(), - message.skippedPreprocessorRanges(), - documentRevision); - } - } -} - -static -CppTools::CursorInfo::Range toCursorInfoRange(const QTextDocument &textDocument, - const SourceRangeContainer &sourceRange) -{ - const SourceLocationContainer start = sourceRange.start(); - const SourceLocationContainer end = sourceRange.end(); - const unsigned length = end.column() - start.column(); - - const QTextBlock block = textDocument.findBlockByNumber(static_cast<int>(start.line()) - 1); - const int shift = ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), - static_cast<int>(start.column())); - const uint column = start.column() - static_cast<uint>(shift); - - return CppTools::CursorInfo::Range(start.line(), column, length); -} - -static -CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses, - const ReferencesMessage &message) -{ - CppTools::CursorInfo result; - const QVector<SourceRangeContainer> references = message.references(); - - result.areUseRangesForLocalVariable = message.isLocalVariable(); - for (const SourceRangeContainer &reference : references) - result.useRanges.append(toCursorInfoRange(textDocument, reference)); - - result.useRanges.reserve(references.size()); - result.localUses = localUses; - - return result; -} - -static -CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message) -{ - CppTools::SymbolInfo result; - const SourceRangeContainer &range = message.sourceRange(); - - const SourceLocationContainer start = range.start(); - const SourceLocationContainer end = range.end(); - result.startLine = static_cast<int>(start.line()); - result.startColumn = static_cast<int>(start.column()); - result.endLine = static_cast<int>(end.line()); - result.endColumn = static_cast<int>(end.column()); - result.fileName = start.filePath(); - - return result; -} - -void IpcReceiver::references(const ReferencesMessage &message) -{ - qCDebug(log) << "<<< ReferencesMessage with" - << message.references().size() << "references"; - - const quint64 ticket = message.ticketNumber(); - const ReferencesEntry entry = m_referencesTable.take(ticket); - QFutureInterface<CppTools::CursorInfo> futureInterface = entry.futureInterface; - QTC_CHECK(futureInterface != QFutureInterface<CppTools::CursorInfo>()); - - if (futureInterface.isCanceled()) - return; // Editor document closed or a new request was issued making this result outdated. - - QTC_ASSERT(entry.textDocument, return); - futureInterface.reportResult(toCursorInfo(*entry.textDocument, entry.localUses, message)); - futureInterface.reportFinished(); -} - -void IpcReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message) -{ - qCDebug(log) << "<<< FollowSymbolMessage with" - << message.sourceRange() << "range"; - - const quint64 ticket = message.ticketNumber(); - QFutureInterface<CppTools::SymbolInfo> futureInterface = m_followTable.take(ticket); - QTC_CHECK(futureInterface != QFutureInterface<CppTools::SymbolInfo>()); - - if (futureInterface.isCanceled()) - return; // Editor document closed or a new request was issued making this result outdated. - - futureInterface.reportResult(toSymbolInfo(message)); - futureInterface.reportFinished(); -} - -IpcSender::IpcSender(ClangCodeModelConnectionClient *connectionClient) - : m_connection(connectionClient) -{} - -void IpcSender::end() -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << ClangBackEnd::EndMessage(); - m_connection->sendEndMessage(); -} - -void IpcSender::registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().registerTranslationUnitsForEditor(message); -} - -void IpcSender::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().updateTranslationUnitsForEditor(message); -} - -void IpcSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().unregisterTranslationUnitsForEditor(message); -} - -void IpcSender::registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().registerProjectPartsForEditor(message); -} - -void IpcSender::unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().unregisterProjectPartsForEditor(message); -} - -void IpcSender::registerUnsavedFilesForEditor(const RegisterUnsavedFilesForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().registerUnsavedFilesForEditor(message); -} - -void IpcSender::unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().unregisterUnsavedFilesForEditor(message); -} - -void IpcSender::completeCode(const CompleteCodeMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().completeCode(message); -} - -void IpcSender::requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().requestDocumentAnnotations(message); -} - -void IpcSender::requestReferences(const RequestReferencesMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().requestReferences(message); -} - -void IpcSender::requestFollowSymbol(const RequestFollowSymbolMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().requestFollowSymbol(message); -} - -void IpcSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().updateVisibleTranslationUnits(message); -} - -bool IpcSender::isConnected() const -{ - return m_connection && m_connection->isConnected(); -} - -class DummyIpcSender : public IpcSender -{ -public: - DummyIpcSender() : IpcSender(nullptr) {} - - void end() override {} - void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &) override {} - void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &) override {} - void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &) override {} - void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &) override {} - void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &) override {} - void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &) override {} - void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &) override {} - void completeCode(const ClangBackEnd::CompleteCodeMessage &) override {} - void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &) override {} - void requestReferences(const ClangBackEnd::RequestReferencesMessage &) override {} - void requestFollowSymbol(const RequestFollowSymbolMessage &) override {} - void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &) override {} -}; - -enum { backEndStartTimeOutInMs = 10000 }; - -IpcCommunicator::IpcCommunicator() - : m_connection(&m_ipcReceiver) - , m_ipcSender(new DummyIpcSender()) -{ - m_backendStartTimeOut.setSingleShot(true); - connect(&m_backendStartTimeOut, &QTimer::timeout, - this, &IpcCommunicator::logStartTimeOut); - - m_ipcReceiver.setAliveHandler([this]() { m_connection.resetProcessAliveTimer(); }); - - connect(Core::EditorManager::instance(), &Core::EditorManager::editorAboutToClose, - this, &IpcCommunicator::onEditorAboutToClose); - connect(Core::ICore::instance(), &Core::ICore::coreAboutToClose, - this, &IpcCommunicator::setupDummySender); - - initializeBackend(); -} - -IpcCommunicator::~IpcCommunicator() -{ - disconnect(&m_connection, 0, this, 0); -} - -void IpcCommunicator::initializeBackend() -{ - const QString clangBackEndProcessPath = backendProcessPath(); - if (!QFileInfo(clangBackEndProcessPath).exists()) { - logExecutableDoesNotExist(); - return; - } - qCDebug(log) << "Starting" << clangBackEndProcessPath; - - m_connection.setProcessAliveTimerInterval(30 * 1000); - m_connection.setProcessPath(clangBackEndProcessPath); - - connect(&m_connection, &ConnectionClient::connectedToLocalSocket, - this, &IpcCommunicator::onConnectedToBackend); - connect(&m_connection, &ConnectionClient::disconnectedFromLocalSocket, - this, &IpcCommunicator::setupDummySender); - - m_connection.startProcessAndConnectToServerAsynchronously(); - m_backendStartTimeOut.start(backEndStartTimeOutInMs); -} - -static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart) -{ - const QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart, - CppTools::ProjectFile::Unsupported); // No language option - - return options; -} - -static ClangBackEnd::ProjectPartContainer toProjectPartContainer( - const CppTools::ProjectPart::Ptr &projectPart) -{ - const QStringList options = projectPartOptions(projectPart); - - return ClangBackEnd::ProjectPartContainer(projectPart->id(), Utf8StringVector(options)); -} - -static QVector<ClangBackEnd::ProjectPartContainer> toProjectPartContainers( - const QVector<CppTools::ProjectPart::Ptr> projectParts) -{ - QVector<ClangBackEnd::ProjectPartContainer> projectPartContainers; - projectPartContainers.reserve(projectParts.size()); - - foreach (const CppTools::ProjectPart::Ptr &projectPart, projectParts) - projectPartContainers << toProjectPartContainer(projectPart); - - return projectPartContainers; -} - -void IpcCommunicator::registerFallbackProjectPart() -{ - const auto projectPart = CppTools::CppModelManager::instance()->fallbackProjectPart(); - const auto projectPartContainer = toProjectPartContainer(projectPart); - - registerProjectPartsForEditor({projectPartContainer}); -} - -namespace { -Utf8String currentCppEditorDocumentFilePath() -{ - Utf8String currentCppEditorDocumentFilePath; - - const auto currentEditor = Core::EditorManager::currentEditor(); - if (currentEditor && CppTools::CppModelManager::isCppEditor(currentEditor)) { - const auto currentDocument = currentEditor->document(); - if (currentDocument) - currentCppEditorDocumentFilePath = currentDocument->filePath().toString(); - } - - return currentCppEditorDocumentFilePath; -} - -void removeDuplicates(Utf8StringVector &visibleEditorDocumentsFilePaths) -{ - std::sort(visibleEditorDocumentsFilePaths.begin(), - visibleEditorDocumentsFilePaths.end()); - const auto end = std::unique(visibleEditorDocumentsFilePaths.begin(), - visibleEditorDocumentsFilePaths.end()); - visibleEditorDocumentsFilePaths.erase(end, - visibleEditorDocumentsFilePaths.end()); -} - -void removeNonCppEditors(QList<Core::IEditor*> &visibleEditors) -{ - const auto isNotCppEditor = [] (Core::IEditor *editor) { - return !CppTools::CppModelManager::isCppEditor(editor); - }; - - const auto end = std::remove_if(visibleEditors.begin(), - visibleEditors.end(), - isNotCppEditor); - - visibleEditors.erase(end, visibleEditors.end()); -} - -Utf8StringVector visibleCppEditorDocumentsFilePaths() -{ - auto visibleEditors = CppTools::CppToolsBridge::visibleEditors(); - - removeNonCppEditors(visibleEditors); - - Utf8StringVector visibleCppEditorDocumentsFilePaths; - visibleCppEditorDocumentsFilePaths.reserve(visibleEditors.size()); - - const auto editorFilePaths = [] (Core::IEditor *editor) { - return Utf8String(editor->document()->filePath().toString()); - }; - - std::transform(visibleEditors.begin(), - visibleEditors.end(), - std::back_inserter(visibleCppEditorDocumentsFilePaths), - editorFilePaths); - - removeDuplicates(visibleCppEditorDocumentsFilePaths); - - return visibleCppEditorDocumentsFilePaths; -} - -} - -void IpcCommunicator::updateTranslationUnitVisiblity() -{ - updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths()); -} - -bool IpcCommunicator::isNotWaitingForCompletion() const -{ - return !m_ipcReceiver.isExpectingCodeCompletedMessage(); -} - -void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, - const Utf8StringVector &visibleEditorsFilePaths) -{ - const UpdateVisibleTranslationUnitsMessage message(currentEditorFilePath, visibleEditorsFilePaths); - m_ipcSender->updateVisibleTranslationUnits(message); -} - -void IpcCommunicator::registerCurrentProjectParts() -{ - using namespace CppTools; - - const QList<ProjectInfo> projectInfos = CppModelManager::instance()->projectInfos(); - foreach (const ProjectInfo &projectInfo, projectInfos) - registerProjectsParts(projectInfo.projectParts()); -} - -void IpcCommunicator::restoreCppEditorDocuments() -{ - resetCppEditorDocumentProcessors(); - registerVisibleCppEditorDocumentAndMarkInvisibleDirty(); -} - -void IpcCommunicator::resetCppEditorDocumentProcessors() -{ - using namespace CppTools; - - const auto cppEditorDocuments = CppModelManager::instance()->cppEditorDocuments(); - foreach (CppEditorDocumentHandle *cppEditorDocument, cppEditorDocuments) - cppEditorDocument->resetProcessor(); -} - -void IpcCommunicator::registerVisibleCppEditorDocumentAndMarkInvisibleDirty() -{ - CppTools::CppModelManager::instance()->updateCppEditorDocuments(); -} - -void IpcCommunicator::registerCurrentCodeModelUiHeaders() -{ - using namespace CppTools; - - const auto editorSupports = CppModelManager::instance()->abstractEditorSupports(); - foreach (const AbstractEditorSupport *es, editorSupports) { - const QString mappedPath - = ModelManagerSupportClang::instance()->dummyUiHeaderOnDiskPath(es->fileName()); - updateUnsavedFile(mappedPath, es->contents(), es->revision()); - } -} - -void IpcCommunicator::registerProjectsParts(const QVector<CppTools::ProjectPart::Ptr> projectParts) -{ - const auto projectPartContainers = toProjectPartContainers(projectParts); - registerProjectPartsForEditor(projectPartContainers); -} - -void IpcCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath) -{ - const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); - - updateTranslationUnit(filePath, document->contents(), document->revision()); -} - -void IpcCommunicator::updateUnsavedFileFromCppEditorDocument(const QString &filePath) -{ - const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); - - updateUnsavedFile(filePath, document->contents(), document->revision()); -} - -namespace { - - -} - -void IpcCommunicator::updateTranslationUnit(const QString &filePath, - const QByteArray &contents, - uint documentRevision) -{ - const bool hasUnsavedContent = true; - - updateTranslationUnitsForEditor({{filePath, - Utf8String(), - Utf8String::fromByteArray(contents), - hasUnsavedContent, - documentRevision}}); -} - -void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision) -{ - const bool hasUnsavedContent = true; - - // TODO: Send new only if changed - registerUnsavedFilesForEditor({{filePath, - Utf8String(), - Utf8String::fromByteArray(contents), - hasUnsavedContent, - documentRevision}}); -} - -static bool documentHasChanged(const QString &filePath, uint revision) -{ - if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) - return document->sendTracker().shouldSendRevision(revision); - - return true; -} - -static void setLastSentDocumentRevision(const QString &filePath, uint revision) -{ - if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) - document->sendTracker().setLastSentRevision(int(revision)); -} - -void IpcCommunicator::updateTranslationUnitWithRevisionCheck(const FileContainer &fileContainer) -{ - if (documentHasChanged(fileContainer.filePath(), fileContainer.documentRevision())) { - updateTranslationUnitsForEditor({fileContainer}); - setLastSentDocumentRevision(fileContainer.filePath(), - fileContainer.documentRevision()); - } -} - -void IpcCommunicator::requestDocumentAnnotations(const FileContainer &fileContainer) -{ - const RequestDocumentAnnotationsMessage message(fileContainer); - m_ipcSender->requestDocumentAnnotations(message); -} - -QFuture<CppTools::CursorInfo> IpcCommunicator::requestReferences( - const FileContainer &fileContainer, - quint32 line, - quint32 column, - QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses) -{ - const RequestReferencesMessage message(fileContainer, line, column); - m_ipcSender->requestReferences(message); - - return m_ipcReceiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument, - localUses); -} - -QFuture<CppTools::SymbolInfo> IpcCommunicator::requestFollowSymbol( - const FileContainer &curFileContainer, - const QVector<Utf8String> &dependentFiles, - quint32 line, - quint32 column) -{ - const RequestFollowSymbolMessage message(curFileContainer, - dependentFiles, - line, - column); - m_ipcSender->requestFollowSymbol(message); - - return m_ipcReceiver.addExpectedRequestFollowSymbolMessage(message.ticketNumber()); -} - -void IpcCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document) -{ - const auto textDocument = qobject_cast<TextDocument*>(document); - const auto filePath = textDocument->filePath().toString(); - const QString projectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); - - updateTranslationUnitWithRevisionCheck(FileContainer(filePath, - projectPartId, - Utf8StringVector(), - textDocument->document()->revision())); -} - -void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath, int position) -{ - if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) - document->sendTracker().applyContentChange(position); -} - -void IpcCommunicator::updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document) -{ - QTC_ASSERT(document, return); - if (Core::EditorManager::currentDocument() != document) - updateTranslationUnit(document); -} - -void IpcCommunicator::updateTranslationUnit(Core::IDocument *document) -{ - updateTranslationUnitFromCppEditorDocument(document->filePath().toString()); -} - -void IpcCommunicator::updateUnsavedFile(Core::IDocument *document) -{ - QTC_ASSERT(document, return); - - updateUnsavedFileFromCppEditorDocument(document->filePath().toString()); -} - -void IpcCommunicator::onConnectedToBackend() -{ - m_backendStartTimeOut.stop(); - - ++m_connectedCount; - if (m_connectedCount > 1) - logRestartedDueToUnexpectedFinish(); - - m_ipcReceiver.reset(); - m_ipcSender.reset(new IpcSender(&m_connection)); - - initializeBackendWithCurrentData(); -} - -void IpcCommunicator::onEditorAboutToClose(Core::IEditor *editor) -{ - if (auto *textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor)) - m_ipcReceiver.deleteProcessorsOfEditorWidget(textEditor->editorWidget()); -} - -void IpcCommunicator::setupDummySender() -{ - m_ipcSender.reset(new DummyIpcSender); -} - -void IpcCommunicator::logExecutableDoesNotExist() -{ - const QString msg - = tr("Clang Code Model: Error: " - "The clangbackend executable \"%1\" does not exist.") - .arg(QDir::toNativeSeparators(backendProcessPath())); - - logError(msg); -} - -void IpcCommunicator::logStartTimeOut() -{ - const QString msg - = tr("Clang Code Model: Error: " - "The clangbackend executable \"%1\" could not be started (timeout after %2ms).") - .arg(QDir::toNativeSeparators(backendProcessPath())) - .arg(backEndStartTimeOutInMs); - - logError(msg); -} - -void IpcCommunicator::logRestartedDueToUnexpectedFinish() -{ - const QString msg - = tr("Clang Code Model: Error: " - "The clangbackend process has finished unexpectedly and was restarted."); - - logError(msg); -} - -void IpcCommunicator::logError(const QString &text) -{ - const QString textWithTimestamp = QDateTime::currentDateTime().toString(Qt::ISODate) - + ' ' + text; - Core::MessageManager::write(textWithTimestamp, Core::MessageManager::Flash); - qWarning("%s", qPrintable(textWithTimestamp)); -} - -void IpcCommunicator::initializeBackendWithCurrentData() -{ - registerFallbackProjectPart(); - registerCurrentProjectParts(); - registerCurrentCodeModelUiHeaders(); - restoreCppEditorDocuments(); - updateTranslationUnitVisiblity(); - - emit backendReinitialized(); -} - -IpcSender *IpcCommunicator::setIpcSender(IpcSender *ipcSender) -{ - IpcSender *previousMessageSender = m_ipcSender.take(); - m_ipcSender.reset(ipcSender); - return previousMessageSender; -} - -void IpcCommunicator::killBackendProcess() -{ - m_connection.processForTestOnly()->kill(); -} - -void IpcCommunicator::registerTranslationUnitsForEditor(const FileContainers &fileContainers) -{ - const RegisterTranslationUnitForEditorMessage message(fileContainers, - currentCppEditorDocumentFilePath(), - visibleCppEditorDocumentsFilePaths()); - m_ipcSender->registerTranslationUnitsForEditor(message); -} - -void IpcCommunicator::updateTranslationUnitsForEditor(const IpcCommunicator::FileContainers &fileContainers) -{ - const UpdateTranslationUnitsForEditorMessage message(fileContainers); - m_ipcSender->updateTranslationUnitsForEditor(message); -} - -void IpcCommunicator::unregisterTranslationUnitsForEditor(const FileContainers &fileContainers) -{ - const UnregisterTranslationUnitsForEditorMessage message(fileContainers); - m_ipcSender->unregisterTranslationUnitsForEditor(message); -} - -void IpcCommunicator::registerProjectPartsForEditor( - const ProjectPartContainers &projectPartContainers) -{ - const RegisterProjectPartsForEditorMessage message(projectPartContainers); - m_ipcSender->registerProjectPartsForEditor(message); -} - -void IpcCommunicator::unregisterProjectPartsForEditor(const QStringList &projectPartIds) -{ - const UnregisterProjectPartsForEditorMessage message((Utf8StringVector(projectPartIds))); - m_ipcSender->unregisterProjectPartsForEditor(message); -} - -void IpcCommunicator::registerUnsavedFilesForEditor(const IpcCommunicator::FileContainers &fileContainers) -{ - const RegisterUnsavedFilesForEditorMessage message(fileContainers); - m_ipcSender->registerUnsavedFilesForEditor(message); -} - -void IpcCommunicator::unregisterUnsavedFilesForEditor(const IpcCommunicator::FileContainers &fileContainers) -{ - const UnregisterUnsavedFilesForEditorMessage message(fileContainers); - m_ipcSender->unregisterUnsavedFilesForEditor(message); -} - -void IpcCommunicator::completeCode(ClangCompletionAssistProcessor *assistProcessor, - const QString &filePath, - quint32 line, - quint32 column, - const QString &projectFilePath, - qint32 funcNameStartLine, - qint32 funcNameStartColumn) -{ - const CompleteCodeMessage message(filePath, line, column, projectFilePath, funcNameStartLine, - funcNameStartColumn); - m_ipcSender->completeCode(message); - m_ipcReceiver.addExpectedCodeCompletedMessage(message.ticketNumber(), assistProcessor); -} diff --git a/src/plugins/clangcodemodel/clangbackendlogging.cpp b/src/plugins/clangcodemodel/clangbackendlogging.cpp new file mode 100644 index 0000000000..47118ca22d --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendlogging.cpp @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangbackendlogging.h" + +namespace ClangCodeModel { +namespace Internal { + +Q_LOGGING_CATEGORY(ipcLog, "qtc.clangcodemodel.ipc") + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendlogging.h b/src/plugins/clangcodemodel/clangbackendlogging.h new file mode 100644 index 0000000000..6e2e3ec689 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendlogging.h @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <QLoggingCategory> + +namespace ClangCodeModel { namespace Internal { + +Q_DECLARE_LOGGING_CATEGORY(ipcLog) + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.cpp b/src/plugins/clangcodemodel/clangbackendreceiver.cpp new file mode 100644 index 0000000000..9d620d6697 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendreceiver.cpp @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangbackendreceiver.h" + +#include "clangbackendlogging.h" + +#include "clangcompletionassistprocessor.h" +#include "clangeditordocumentprocessor.h" + +#include <cpptools/cpptoolsbridge.h> + +#include <clangsupport/clangcodemodelclientmessages.h> + +#include <QLoggingCategory> +#include <QTextBlock> + +#include <utils/qtcassert.h> + +static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.ipc") + +using namespace ClangBackEnd; + +namespace ClangCodeModel { +namespace Internal { + +static bool printAliveMessageHelper() +{ + const bool print = qEnvironmentVariableIntValue("QTC_CLANG_FORCE_VERBOSE_ALIVE"); + if (!print) { + qCDebug(log) << "Hint: AliveMessage will not be printed. " + "Force it by setting QTC_CLANG_FORCE_VERBOSE_ALIVE=1."; + } + + return print; +} + +static bool printAliveMessage() +{ + static bool print = log().isDebugEnabled() ? printAliveMessageHelper() : false; + return print; +} + +BackendReceiver::BackendReceiver() +{ +} + +BackendReceiver::~BackendReceiver() +{ + reset(); +} + +void BackendReceiver::setAliveHandler(const BackendReceiver::AliveHandler &handler) +{ + m_aliveHandler = handler; +} + +void BackendReceiver::addExpectedCodeCompletedMessage( + quint64 ticket, + ClangCompletionAssistProcessor *processor) +{ + QTC_ASSERT(processor, return); + QTC_CHECK(!m_assistProcessorsTable.contains(ticket)); + m_assistProcessorsTable.insert(ticket, processor); +} + +void BackendReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget) +{ + QMutableHashIterator<quint64, ClangCompletionAssistProcessor *> it(m_assistProcessorsTable); + while (it.hasNext()) { + it.next(); + ClangCompletionAssistProcessor *assistProcessor = it.value(); + if (assistProcessor->textEditorWidget() == textEditorWidget) { + delete assistProcessor; + it.remove(); + } + } +} + +QFuture<CppTools::CursorInfo> BackendReceiver::addExpectedReferencesMessage( + quint64 ticket, + QTextDocument *textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses) +{ + QTC_CHECK(textDocument); + QTC_CHECK(!m_referencesTable.contains(ticket)); + + QFutureInterface<CppTools::CursorInfo> futureInterface; + futureInterface.reportStarted(); + + const ReferencesEntry entry{futureInterface, textDocument, localUses}; + m_referencesTable.insert(ticket, entry); + + return futureInterface.future(); +} + +QFuture<CppTools::SymbolInfo> BackendReceiver::addExpectedRequestFollowSymbolMessage(quint64 ticket) +{ + QTC_CHECK(!m_followTable.contains(ticket)); + + QFutureInterface<CppTools::SymbolInfo> futureInterface; + futureInterface.reportStarted(); + + m_followTable.insert(ticket, futureInterface); + + return futureInterface.future(); +} + +bool BackendReceiver::isExpectingCodeCompletedMessage() const +{ + return !m_assistProcessorsTable.isEmpty(); +} + +void BackendReceiver::reset() +{ + // Clean up waiting assist processors + qDeleteAll(m_assistProcessorsTable.begin(), m_assistProcessorsTable.end()); + m_assistProcessorsTable.clear(); + + // Clean up futures for references + for (ReferencesEntry &entry : m_referencesTable) + entry.futureInterface.cancel(); + m_referencesTable.clear(); + for (QFutureInterface<CppTools::SymbolInfo> &futureInterface : m_followTable) + futureInterface.cancel(); + m_followTable.clear(); +} + +void BackendReceiver::alive() +{ + if (printAliveMessage()) + qCDebug(log) << "<<< AliveMessage"; + QTC_ASSERT(m_aliveHandler, return); + m_aliveHandler(); +} + +void BackendReceiver::echo(const EchoMessage &message) +{ + qCDebug(log) << "<<<" << message; +} + +void BackendReceiver::codeCompleted(const CodeCompletedMessage &message) +{ + qCDebug(log) << "<<< CodeCompletedMessage with" << message.codeCompletions().size() << "items"; + + const quint64 ticket = message.ticketNumber(); + QScopedPointer<ClangCompletionAssistProcessor> processor(m_assistProcessorsTable.take(ticket)); + if (processor) { + processor->handleAvailableCompletions(message.codeCompletions(), + message.neededCorrection()); + } +} + +void BackendReceiver::documentAnnotationsChanged(const DocumentAnnotationsChangedMessage &message) +{ + qCDebug(log) << "<<< DocumentAnnotationsChangedMessage with" + << message.diagnostics().size() << "diagnostics" + << message.highlightingMarks().size() << "highlighting marks" + << message.skippedPreprocessorRanges().size() << "skipped preprocessor ranges"; + + auto processor = ClangEditorDocumentProcessor::get(message.fileContainer().filePath()); + + if (processor) { + const QString projectPartId = message.fileContainer().projectPartId(); + const QString filePath = message.fileContainer().filePath(); + const QString documentProjectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); + if (projectPartId == documentProjectPartId) { + const quint32 documentRevision = message.fileContainer().documentRevision(); + processor->updateCodeWarnings(message.diagnostics(), + message.firstHeaderErrorDiagnostic(), + documentRevision); + processor->updateHighlighting(message.highlightingMarks(), + message.skippedPreprocessorRanges(), + documentRevision); + } + } +} + +static +CppTools::CursorInfo::Range toCursorInfoRange(const QTextDocument &textDocument, + const SourceRangeContainer &sourceRange) +{ + const SourceLocationContainer start = sourceRange.start(); + const SourceLocationContainer end = sourceRange.end(); + const unsigned length = end.column() - start.column(); + + const QTextBlock block = textDocument.findBlockByNumber(static_cast<int>(start.line()) - 1); + const int shift = ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), + static_cast<int>(start.column())); + const uint column = start.column() - static_cast<uint>(shift); + + return CppTools::CursorInfo::Range(start.line(), column, length); +} + +static +CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses, + const ReferencesMessage &message) +{ + CppTools::CursorInfo result; + const QVector<SourceRangeContainer> references = message.references(); + + result.areUseRangesForLocalVariable = message.isLocalVariable(); + for (const SourceRangeContainer &reference : references) + result.useRanges.append(toCursorInfoRange(textDocument, reference)); + + result.useRanges.reserve(references.size()); + result.localUses = localUses; + + return result; +} + +static +CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message) +{ + CppTools::SymbolInfo result; + const SourceRangeContainer &range = message.sourceRange(); + + const SourceLocationContainer start = range.start(); + const SourceLocationContainer end = range.end(); + result.startLine = static_cast<int>(start.line()); + result.startColumn = static_cast<int>(start.column()); + result.endLine = static_cast<int>(end.line()); + result.endColumn = static_cast<int>(end.column()); + result.fileName = start.filePath(); + + return result; +} + +void BackendReceiver::references(const ReferencesMessage &message) +{ + qCDebug(log) << "<<< ReferencesMessage with" + << message.references().size() << "references"; + + const quint64 ticket = message.ticketNumber(); + const ReferencesEntry entry = m_referencesTable.take(ticket); + QFutureInterface<CppTools::CursorInfo> futureInterface = entry.futureInterface; + QTC_CHECK(futureInterface != QFutureInterface<CppTools::CursorInfo>()); + + if (futureInterface.isCanceled()) + return; // Editor document closed or a new request was issued making this result outdated. + + QTC_ASSERT(entry.textDocument, return); + futureInterface.reportResult(toCursorInfo(*entry.textDocument, entry.localUses, message)); + futureInterface.reportFinished(); +} + +void BackendReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message) +{ + qCDebug(log) << "<<< FollowSymbolMessage with" + << message.sourceRange() << "range"; + + const quint64 ticket = message.ticketNumber(); + QFutureInterface<CppTools::SymbolInfo> futureInterface = m_followTable.take(ticket); + QTC_CHECK(futureInterface != QFutureInterface<CppTools::SymbolInfo>()); + + if (futureInterface.isCanceled()) + return; // Editor document closed or a new request was issued making this result outdated. + + futureInterface.reportResult(toSymbolInfo(message)); + futureInterface.reportFinished(); +} + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.h b/src/plugins/clangcodemodel/clangbackendreceiver.h new file mode 100644 index 0000000000..d67db73223 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendreceiver.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <cpptools/cppcursorinfo.h> +#include <cpptools/cppsymbolinfo.h> + +#include <clangsupport/clangcodemodelclientinterface.h> + +#include <QFuture> +#include <QPointer> +#include <QTextDocument> + +namespace TextEditor { class TextEditorWidget; } + +namespace ClangCodeModel { +namespace Internal { + +class ClangCompletionAssistProcessor; + +class BackendReceiver : public ClangBackEnd::ClangCodeModelClientInterface +{ +public: + BackendReceiver(); + ~BackendReceiver() override; + + using AliveHandler = std::function<void ()>; + void setAliveHandler(const AliveHandler &handler); + + void addExpectedCodeCompletedMessage(quint64 ticket, ClangCompletionAssistProcessor *processor); + void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget); + + QFuture<CppTools::CursorInfo> + addExpectedReferencesMessage(quint64 ticket, + QTextDocument *textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses); + QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket); + bool isExpectingCodeCompletedMessage() const; + + void reset(); + +private: + void alive() override; + void echo(const ClangBackEnd::EchoMessage &message) override; + void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override; + + void documentAnnotationsChanged(const ClangBackEnd::DocumentAnnotationsChangedMessage &message) override; + void references(const ClangBackEnd::ReferencesMessage &message) override; + void followSymbol(const ClangBackEnd::FollowSymbolMessage &message) override; + +private: + AliveHandler m_aliveHandler; + QHash<quint64, ClangCompletionAssistProcessor *> m_assistProcessorsTable; + + struct ReferencesEntry { + ReferencesEntry() = default; + ReferencesEntry(QFutureInterface<CppTools::CursorInfo> futureInterface, + QTextDocument *textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses) + : futureInterface(futureInterface) + , textDocument(textDocument) + , localUses(localUses) {} + QFutureInterface<CppTools::CursorInfo> futureInterface; + QPointer<QTextDocument> textDocument; + CppTools::SemanticInfo::LocalUseMap localUses; + }; + QHash<quint64, ReferencesEntry> m_referencesTable; + + QHash<quint64, QFutureInterface<CppTools::SymbolInfo>> m_followTable; +}; + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendsender.cpp b/src/plugins/clangcodemodel/clangbackendsender.cpp new file mode 100644 index 0000000000..b43b5dee4e --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendsender.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangbackendsender.h" + +#include "clangbackendlogging.h" + +#include <clangsupport/clangcodemodelconnectionclient.h> +#include <clangsupport/clangcodemodelservermessages.h> + +#include <utils/qtcassert.h> + +using namespace ClangBackEnd; + +namespace ClangCodeModel { +namespace Internal { + +BackendSender::BackendSender(ClangCodeModelConnectionClient *connectionClient) + : m_connection(connectionClient) +{} + +void BackendSender::end() +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << ClangBackEnd::EndMessage(); + m_connection->sendEndMessage(); +} + +void BackendSender::registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().registerTranslationUnitsForEditor(message); +} + +void BackendSender::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().updateTranslationUnitsForEditor(message); +} + +void BackendSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().unregisterTranslationUnitsForEditor(message); +} + +void BackendSender::registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().registerProjectPartsForEditor(message); +} + +void BackendSender::unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().unregisterProjectPartsForEditor(message); +} + +void BackendSender::registerUnsavedFilesForEditor(const RegisterUnsavedFilesForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().registerUnsavedFilesForEditor(message); +} + +void BackendSender::unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().unregisterUnsavedFilesForEditor(message); +} + +void BackendSender::completeCode(const CompleteCodeMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().completeCode(message); +} + +void BackendSender::requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().requestDocumentAnnotations(message); +} + +void BackendSender::requestReferences(const RequestReferencesMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().requestReferences(message); +} + +void BackendSender::requestFollowSymbol(const RequestFollowSymbolMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().requestFollowSymbol(message); +} + +void BackendSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().updateVisibleTranslationUnits(message); +} + +bool BackendSender::isConnected() const +{ + return m_connection && m_connection->isConnected(); +} + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendsender.h b/src/plugins/clangcodemodel/clangbackendsender.h new file mode 100644 index 0000000000..ca9238ae65 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendsender.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <clangsupport/clangcodemodelserverinterface.h> + +namespace ClangBackEnd { class ClangCodeModelConnectionClient; } + +namespace ClangCodeModel { +namespace Internal { + +class BackendSender : public ClangBackEnd::ClangCodeModelServerInterface +{ +public: + BackendSender(ClangBackEnd::ClangCodeModelConnectionClient *connectionClient); + + void end() override; + void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override; + void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override; + void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override; + void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override; + void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override; + void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &message) override; + void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override; + void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; + void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) override; + void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) override; + void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) override; + void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) override; + +private: + bool isConnected() const; + +private: + ClangBackEnd::ClangCodeModelConnectionClient *m_connection = nullptr; +}; + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index d48ce960de..9f632dd464 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -9,7 +9,10 @@ SOURCES += \ clangassistproposal.cpp \ clangassistproposalitem.cpp \ clangassistproposalmodel.cpp \ - clangbackendipcintegration.cpp \ + clangbackendcommunicator.cpp \ + clangbackendlogging.cpp \ + clangbackendreceiver.cpp \ + clangbackendsender.cpp \ clangcodemodelplugin.cpp \ clangcompletionassistinterface.cpp \ clangcompletionassistprocessor.cpp \ @@ -40,7 +43,10 @@ HEADERS += \ clangassistproposal.h \ clangassistproposalitem.h \ clangassistproposalmodel.h \ - clangbackendipcintegration.h \ + clangbackendcommunicator.h \ + clangbackendlogging.h \ + clangbackendreceiver.h \ + clangbackendsender.h \ clangcodemodelplugin.h \ clangcompletionassistinterface.h \ clangcompletionassistprocessor.h \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index 699e573032..cfee39fdbf 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -41,8 +41,14 @@ QtcPlugin { "clangassistproposalitem.h", "clangassistproposalmodel.cpp", "clangassistproposalmodel.h", - "clangbackendipcintegration.cpp", - "clangbackendipcintegration.h", + "clangbackendcommunicator.cpp", + "clangbackendcommunicator.h", + "clangbackendlogging.cpp", + "clangbackendlogging.h", + "clangbackendreceiver.cpp", + "clangbackendreceiver.h", + "clangbackendsender.cpp", + "clangbackendsender.h", "clangcodemodelplugin.cpp", "clangcodemodelplugin.h", "clangcodemodel.qrc", diff --git a/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp b/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp index 57e2cbcdf1..0f5ec7bc1d 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp @@ -31,7 +31,7 @@ namespace ClangCodeModel { namespace Internal { ClangCompletionAssistInterface::ClangCompletionAssistInterface( - IpcCommunicator &ipcCommunicator, + BackendCommunicator &communicator, const TextEditor::TextEditorWidget *textEditorWidget, int position, const QString &fileName, @@ -39,7 +39,7 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface( const CppTools::ProjectPartHeaderPaths &headerPaths, const CPlusPlus::LanguageFeatures &features) : AssistInterface(textEditorWidget->document(), position, fileName, reason) - , m_ipcCommunicator(ipcCommunicator) + , m_communicator(communicator) , m_headerPaths(headerPaths) , m_languageFeatures(features) , m_textEditorWidget(textEditorWidget) @@ -71,9 +71,9 @@ const TextEditor::TextEditorWidget *ClangCompletionAssistInterface::textEditorWi return m_textEditorWidget; } -IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const +BackendCommunicator &ClangCompletionAssistInterface::communicator() const { - return m_ipcCommunicator; + return m_communicator; } } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangcompletionassistinterface.h b/src/plugins/clangcodemodel/clangcompletionassistinterface.h index fc0724777e..df198d8fcf 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistinterface.h +++ b/src/plugins/clangcodemodel/clangcompletionassistinterface.h @@ -25,7 +25,7 @@ #pragma once -#include "clangbackendipcintegration.h" +#include "clangbackendcommunicator.h" #include "clangutils.h" #include <texteditor/codeassist/assistinterface.h> @@ -36,7 +36,7 @@ namespace Internal { class ClangCompletionAssistInterface: public TextEditor::AssistInterface { public: - ClangCompletionAssistInterface(IpcCommunicator &ipcCommunicator, + ClangCompletionAssistInterface(BackendCommunicator &communicator, const TextEditor::TextEditorWidget *textEditorWidget, int position, const QString &fileName, @@ -44,7 +44,7 @@ public: const CppTools::ProjectPartHeaderPaths &headerPaths, const CPlusPlus::LanguageFeatures &features); - IpcCommunicator &ipcCommunicator() const; + BackendCommunicator &communicator() const; bool objcEnabled() const; const CppTools::ProjectPartHeaderPaths &headerPaths() const; CPlusPlus::LanguageFeatures languageFeatures() const; @@ -53,7 +53,7 @@ public: void setHeaderPaths(const CppTools::ProjectPartHeaderPaths &headerPaths); // For tests private: - IpcCommunicator &m_ipcCommunicator; + BackendCommunicator &m_communicator; QStringList m_options; CppTools::ProjectPartHeaderPaths m_headerPaths; CPlusPlus::LanguageFeatures m_languageFeatures; diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index e60ac37ec6..54d960ff03 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -495,12 +495,12 @@ void ClangCompletionAssistProcessor::sendFileContent(const QByteArray &customFil // TODO: Revert custom modification after the completions const UnsavedFileContentInfo info = unsavedFileContent(customFileContent); - IpcCommunicator &ipcCommunicator = m_interface->ipcCommunicator(); - ipcCommunicator.updateTranslationUnitsForEditor({{m_interface->fileName(), - Utf8String(), - Utf8String::fromByteArray(info.unsavedContent), - info.isDocumentModified, - uint(m_interface->textDocument()->revision())}}); + BackendCommunicator &communicator = m_interface->communicator(); + communicator.updateTranslationUnitsForEditor({{m_interface->fileName(), + Utf8String(), + Utf8String::fromByteArray(info.unsavedContent), + info.isDocumentModified, + uint(m_interface->textDocument()->revision())}}); } namespace { bool shouldSendDocumentForCompletion(const QString &filePath, @@ -568,10 +568,9 @@ bool ClangCompletionAssistProcessor::sendCompletionRequest(int position, { const QString filePath = m_interface->fileName(); - auto &ipcCommunicator = m_interface->ipcCommunicator(); + auto &communicator = m_interface->communicator(); - if (shouldSendCodeCompletion(filePath, position) - || ipcCommunicator.isNotWaitingForCompletion()) { + if (shouldSendCodeCompletion(filePath, position) || communicator.isNotWaitingForCompletion()) { if (shouldSendDocumentForCompletion(filePath, position)) { sendFileContent(customFileContent); setLastDocumentRevision(filePath); @@ -580,9 +579,9 @@ bool ClangCompletionAssistProcessor::sendCompletionRequest(int position, const Position cursorPosition = extractLineColumn(position); const Position functionNameStart = extractLineColumn(functionNameStartPosition); const QString projectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); - ipcCommunicator.completeCode(this, filePath, uint(cursorPosition.line), - uint(cursorPosition.column), projectPartId, - functionNameStart.line, functionNameStart.column); + communicator.completeCode(this, filePath, uint(cursorPosition.line), + uint(cursorPosition.column), projectPartId, + functionNameStart.line, functionNameStart.column); setLastCompletionPosition(filePath, position); return true; } diff --git a/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp b/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp index 99abf8ab25..64b97957e7 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp @@ -43,8 +43,8 @@ namespace ClangCodeModel { namespace Internal { -ClangCompletionAssistProvider::ClangCompletionAssistProvider(IpcCommunicator &ipcCommunicator) - : m_ipcCommunicator(ipcCommunicator) +ClangCompletionAssistProvider::ClangCompletionAssistProvider(BackendCommunicator &communicator) + : m_communicator(communicator) { } @@ -67,7 +67,7 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac { const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath); if (projectPart) { - return new ClangCompletionAssistInterface(m_ipcCommunicator, + return new ClangCompletionAssistInterface(m_communicator, textEditorWidget, position, filePath, diff --git a/src/plugins/clangcodemodel/clangcompletionassistprovider.h b/src/plugins/clangcodemodel/clangcompletionassistprovider.h index 7c1ac168be..12139b35d7 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprovider.h +++ b/src/plugins/clangcodemodel/clangcompletionassistprovider.h @@ -25,7 +25,7 @@ #pragma once -#include "clangbackendipcintegration.h" +#include "clangbackendcommunicator.h" #include <cpptools/cppcompletionassistprovider.h> @@ -39,7 +39,7 @@ class ClangCompletionAssistProvider : public CppTools::CppCompletionAssistProvid Q_OBJECT public: - ClangCompletionAssistProvider(IpcCommunicator &ipcCommunicator); + ClangCompletionAssistProvider(BackendCommunicator &communicator); IAssistProvider::RunType runType() const override; @@ -52,7 +52,7 @@ public: TextEditor::AssistReason reason) const override; private: - IpcCommunicator &m_ipcCommunicator; + BackendCommunicator &m_communicator; }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 81053cef60..3d2f2f5267 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -25,7 +25,7 @@ #include "clangeditordocumentprocessor.h" -#include "clangbackendipcintegration.h" +#include "clangbackendcommunicator.h" #include "clangdiagnostictooltipwidget.h" #include "clangfixitoperation.h" #include "clangfixitoperationsextractor.h" @@ -67,12 +67,12 @@ namespace ClangCodeModel { namespace Internal { ClangEditorDocumentProcessor::ClangEditorDocumentProcessor( - IpcCommunicator &ipcCommunicator, + BackendCommunicator &communicator, TextEditor::TextDocument *document) : BaseEditorDocumentProcessor(document->document(), document->filePath().toString()) , m_document(*document) , m_diagnosticManager(document) - , m_ipcCommunicator(ipcCommunicator) + , m_communicator(communicator) , m_parser(new ClangEditorDocumentParser(document->filePath().toString())) , m_parserRevision(0) , m_semanticHighlighter(document) @@ -102,7 +102,7 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor() m_parserWatcher.waitForFinished(); if (m_projectPart) { - m_ipcCommunicator.unregisterTranslationUnitsForEditor( + m_communicator.unregisterTranslationUnitsForEditor( {ClangBackEnd::FileContainer(filePath(), m_projectPart->id())}); } } @@ -343,11 +343,11 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams ¶m const CppTools::SemanticInfo::LocalUseMap localUses = CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column); - return m_ipcCommunicator.requestReferences(simpleFileContainer(), - static_cast<quint32>(line), - static_cast<quint32>(column), - textDocument(), - localUses); + return m_communicator.requestReferences(simpleFileContainer(), + static_cast<quint32>(line), + static_cast<quint32>(column), + textDocument(), + localUses); } static QVector<Utf8String> prioritizeByBaseName(const QString &curPath, @@ -392,10 +392,10 @@ ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column) dependentFiles = prioritizeByBaseName(filePath(), fileDeps); } - return m_ipcCommunicator.requestFollowSymbol(simpleFileContainer(), - dependentFiles, - static_cast<quint32>(line), - static_cast<quint32>(column)); + return m_communicator.requestFollowSymbol(simpleFileContainer(), + dependentFiles, + static_cast<quint32>(line), + static_cast<quint32>(column)); } ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const @@ -456,10 +456,10 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::Pr if (m_projectPart) { if (projectPart->id() == m_projectPart->id()) return; - m_ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()}); + m_communicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()}); } - m_ipcCommunicator.registerTranslationUnitsForEditor( + m_communicator.registerTranslationUnitsForEditor( {fileContainerWithArgumentsAndDocumentContent(projectPart)}); ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision()); } @@ -469,7 +469,7 @@ void ClangEditorDocumentProcessor::updateTranslationUnitIfProjectPartExists() if (m_projectPart) { const ClangBackEnd::FileContainer fileContainer = fileContainerWithDocumentContent(m_projectPart->id()); - m_ipcCommunicator.updateTranslationUnitWithRevisionCheck(fileContainer); + m_communicator.updateTranslationUnitWithRevisionCheck(fileContainer); } } @@ -477,7 +477,7 @@ void ClangEditorDocumentProcessor::requestDocumentAnnotations(const QString &pro { const auto fileContainer = fileContainerWithDocumentContent(projectpartId); - m_ipcCommunicator.requestDocumentAnnotations(fileContainer); + m_communicator.requestDocumentAnnotations(fileContainer); } CppTools::BaseEditorDocumentProcessor::HeaderErrorDiagnosticWidgetCreator diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index d7f7f966f5..a040cba256 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -43,14 +43,14 @@ class FileContainer; namespace ClangCodeModel { namespace Internal { -class IpcCommunicator; +class BackendCommunicator; class ClangEditorDocumentProcessor : public CppTools::BaseEditorDocumentProcessor { Q_OBJECT public: - ClangEditorDocumentProcessor(IpcCommunicator &ipcCommunicator, + ClangEditorDocumentProcessor(BackendCommunicator &communicator, TextEditor::TextDocument *document); ~ClangEditorDocumentProcessor(); @@ -114,7 +114,7 @@ private: private: TextEditor::TextDocument &m_document; ClangDiagnosticManager m_diagnosticManager; - IpcCommunicator &m_ipcCommunicator; + BackendCommunicator &m_communicator; QSharedPointer<ClangEditorDocumentParser> m_parser; CppTools::ProjectPart::Ptr m_projectPart; bool m_isProjectFile = false; diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index c5d85045c5..df1e96869c 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -66,7 +66,7 @@ static CppTools::CppModelManager *cppModelManager() } ModelManagerSupportClang::ModelManagerSupportClang() - : m_completionAssistProvider(m_ipcCommunicator) + : m_completionAssistProvider(m_communicator) { QTC_CHECK(!m_instance); m_instance = this; @@ -96,7 +96,7 @@ ModelManagerSupportClang::ModelManagerSupportClang() connect(modelManager, &CppTools::CppModelManager::projectPartsRemoved, this, &ModelManagerSupportClang::onProjectPartsRemoved); - m_ipcCommunicator.registerFallbackProjectPart(); + m_communicator.registerFallbackProjectPart(); } ModelManagerSupportClang::~ModelManagerSupportClang() @@ -117,12 +117,12 @@ CppTools::FollowSymbolInterface &ModelManagerSupportClang::followSymbolInterface CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) { - return new ClangEditorDocumentProcessor(m_ipcCommunicator, baseTextDocument); + return new ClangEditorDocumentProcessor(m_communicator, baseTextDocument); } void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *) { - m_ipcCommunicator.updateTranslationUnitVisiblity(); + m_communicator.updateTranslationUnitVisiblity(); } void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument) @@ -195,7 +195,7 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor) void ModelManagerSupportClang::onEditorClosed(const QList<Core::IEditor *> &) { - m_ipcCommunicator.updateTranslationUnitVisiblity(); + m_communicator.updateTranslationUnitVisiblity(); } void ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit() @@ -210,7 +210,7 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool if (success) { TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender()); connectToTextDocumentContentsChangedForTranslationUnit(textDocument); - m_ipcCommunicator.updateTranslationUnitWithRevisionCheck(textDocument); + m_communicator.updateTranslationUnitWithRevisionCheck(textDocument); } } @@ -229,9 +229,9 @@ void ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit(int { Core::IDocument *document = qobject_cast<Core::IDocument *>(sender()); - m_ipcCommunicator.updateChangeContentStartPosition(document->filePath().toString(), + m_communicator.updateChangeContentStartPosition(document->filePath().toString(), position); - m_ipcCommunicator.updateTranslationUnitIfNotCurrentDocument(document); + m_communicator.updateTranslationUnitIfNotCurrentDocument(document); clearDiagnosticFixIts(document->filePath().toString()); } @@ -248,14 +248,14 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnUnsavedFile(bool suc if (success) { TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender()); connectToTextDocumentContentsChangedForUnsavedFile(textDocument); - m_ipcCommunicator.updateUnsavedFile(textDocument); + m_communicator.updateUnsavedFile(textDocument); } } void ModelManagerSupportClang::onCppDocumentContentsChangedOnUnsavedFile() { Core::IDocument *document = qobject_cast<Core::IDocument *>(sender()); - m_ipcCommunicator.updateUnsavedFile(document); + m_communicator.updateUnsavedFile(document); } void ModelManagerSupportClang::onAbstractEditorSupportContentsUpdated(const QString &filePath, @@ -264,7 +264,7 @@ void ModelManagerSupportClang::onAbstractEditorSupportContentsUpdated(const QStr QTC_ASSERT(!filePath.isEmpty(), return); const QString mappedPath = m_uiHeaderOnDiskManager.createIfNeeded(filePath); - m_ipcCommunicator.updateUnsavedFile(mappedPath, content, 0); + m_communicator.updateUnsavedFile(mappedPath, content, 0); } void ModelManagerSupportClang::onAbstractEditorSupportRemoved(const QString &filePath) @@ -274,7 +274,7 @@ void ModelManagerSupportClang::onAbstractEditorSupportRemoved(const QString &fil if (!cppModelManager()->cppEditorDocument(filePath)) { const QString mappedPath = m_uiHeaderOnDiskManager.remove(filePath); const QString projectPartId = Utils::projectPartIdForFile(filePath); - m_ipcCommunicator.unregisterUnsavedFilesForEditor({{mappedPath, projectPartId}}); + m_communicator.unregisterUnsavedFilesForEditor({{mappedPath, projectPartId}}); } } @@ -328,16 +328,16 @@ void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *p const CppTools::ProjectInfo projectInfo = cppModelManager()->projectInfo(project); QTC_ASSERT(projectInfo.isValid(), return); - m_ipcCommunicator.registerProjectsParts(projectInfo.projectParts()); - m_ipcCommunicator.registerFallbackProjectPart(); + m_communicator.registerProjectsParts(projectInfo.projectParts()); + m_communicator.registerFallbackProjectPart(); } void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectPartIds) { if (!projectPartIds.isEmpty()) { unregisterTranslationUnitsWithProjectParts(projectPartIds); - m_ipcCommunicator.unregisterProjectPartsForEditor(projectPartIds); - m_ipcCommunicator.registerFallbackProjectPart(); + m_communicator.unregisterProjectPartsForEditor(projectPartIds); + m_communicator.registerFallbackProjectPart(); } } @@ -363,7 +363,7 @@ void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts( { const auto processors = clangProcessorsWithProjectParts(projectPartIds); foreach (ClangEditorDocumentProcessor *processor, processors) { - m_ipcCommunicator.unregisterTranslationUnitsForEditor({processor->fileContainerWithArguments()}); + m_communicator.unregisterTranslationUnitsForEditor({processor->fileContainerWithArguments()}); processor->clearProjectPart(); processor->run(); } @@ -374,9 +374,9 @@ ModelManagerSupportClang *ModelManagerSupportClang::instance() return m_instance; } -IpcCommunicator &ModelManagerSupportClang::ipcCommunicator() +BackendCommunicator &ModelManagerSupportClang::communicator() { - return m_ipcCommunicator; + return m_communicator; } QString ModelManagerSupportClang::dummyUiHeaderOnDiskPath(const QString &filePath) const diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 78e5cd5694..f87ac11923 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -62,7 +62,7 @@ public: TextEditor::TextDocument *baseTextDocument) override; CppTools::FollowSymbolInterface &followSymbolInterface() override; - IpcCommunicator &ipcCommunicator(); + BackendCommunicator &communicator(); QString dummyUiHeaderOnDiskDirPath() const; QString dummyUiHeaderOnDiskPath(const QString &filePath) const; @@ -102,7 +102,7 @@ private: private: UiHeaderOnDiskManager m_uiHeaderOnDiskManager; - IpcCommunicator m_ipcCommunicator; + BackendCommunicator m_communicator; ClangCompletionAssistProvider m_completionAssistProvider; std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol; }; diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp index 25bdff2760..1f5785f86b 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp @@ -170,7 +170,7 @@ void ClangStaticAnalyzerTool::startTool() auto clangTool = new ClangStaticAnalyzerToolRunner(runControl, project->activeTarget()); m_stopAction->disconnect(); - connect(m_stopAction, &QAction::triggered, runControl, [this, runControl] { + connect(m_stopAction, &QAction::triggered, runControl, [runControl] { runControl->appendMessage(tr("Clang Static Analyzer stopped by user."), NormalMessageFormat); runControl->initiateStop(); diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index b64898d2b4..a8b5e0b56a 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -58,18 +58,13 @@ namespace Internal { // BuildDirManager: // -------------------------------------------------------------------- -BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) : - m_buildConfiguration(bc) -{ - QTC_ASSERT(bc, return); -} - +BuildDirManager::BuildDirManager() = default; BuildDirManager::~BuildDirManager() = default; -const Utils::FileName BuildDirManager::workDirectory() const +Utils::FileName BuildDirManager::workDirectory(const BuildDirParameters ¶meters) const { - const Utils::FileName bdir = m_buildConfiguration->buildDirectory(); - const CMakeTool *cmake = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit()); + const Utils::FileName bdir = parameters.buildDirectory; + const CMakeTool *cmake = parameters.cmakeTool; if (bdir.exists()) { return bdir; } else { @@ -102,21 +97,21 @@ void BuildDirManager::emitErrorOccured(const QString &message) const m_isHandlingError = false; } -void BuildDirManager::updateReaderType(std::function<void()> todo) +void BuildDirManager::updateReaderType(const BuildDirParameters &p, + std::function<void()> todo) { - BuildDirReader::Parameters p(m_buildConfiguration); - p.buildDirectory = workDirectory(); - if (!m_reader || !m_reader->isCompatible(p)) { m_reader.reset(BuildDirReader::createReader(p)); connect(m_reader.get(), &BuildDirReader::configurationStarted, - this, &BuildDirManager::configurationStarted); + this, &BuildDirManager::parsingStarted); connect(m_reader.get(), &BuildDirReader::dataAvailable, this, &BuildDirManager::emitDataAvailable); connect(m_reader.get(), &BuildDirReader::errorOccured, this, &BuildDirManager::emitErrorOccured); connect(m_reader.get(), &BuildDirReader::dirty, this, &BuildDirManager::becameDirty); } + QTC_ASSERT(m_reader, return); + m_reader->setParameters(p); if (m_reader->isReady()) @@ -125,27 +120,7 @@ void BuildDirManager::updateReaderType(std::function<void()> todo) connect(m_reader.get(), &BuildDirReader::isReadyNow, this, todo); } -void BuildDirManager::updateReaderData() -{ - BuildDirReader::Parameters p(m_buildConfiguration); - p.buildDirectory = workDirectory(); - - m_reader->setParameters(p); -} - -void BuildDirManager::parseOnceReaderReady(bool force, bool checkForChanges) -{ - TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); - - m_buildTargets.clear(); - m_cmakeCache.clear(); - if (checkForChanges) - checkConfiguration(); - m_reader->stop(); - m_reader->parse(force); -} - -void BuildDirManager::maybeForceReparseOnceReaderReady() +bool BuildDirManager::hasConfigChanged() { checkConfiguration(); @@ -158,14 +133,13 @@ void BuildDirManager::maybeForceReparseOnceReaderReady() const QByteArrayList criticalKeys = {GENERATOR_KEY, CMAKE_COMMAND_KEY, CMAKE_C_COMPILER_KEY, CMAKE_CXX_COMPILER_KEY}; - const CMakeConfig currentConfig = parsedConfiguration(); + const CMakeConfig currentConfig = takeCMakeConfiguration(); - Kit *k = m_buildConfiguration->target()->kit(); - const CMakeTool *tool = CMakeKitInformation::cmakeTool(k); - QTC_ASSERT(tool, return); // No cmake... we should not have ended up here in the first place - const QString extraKitGenerator = CMakeGeneratorKitInformation::extraGenerator(k); - const QString mainKitGenerator = CMakeGeneratorKitInformation::generator(k); - CMakeConfig targetConfig = m_buildConfiguration->cmakeConfiguration(); + const CMakeTool *tool = m_parameters.cmakeTool; + QTC_ASSERT(tool, return false); // No cmake... we should not have ended up here in the first place + const QString extraKitGenerator = m_parameters.extraGenerator; + const QString mainKitGenerator = m_parameters.generator; + CMakeConfig targetConfig = m_parameters.configuration; targetConfig.append(CMakeConfigItem(GENERATOR_KEY, CMakeConfigItem::INTERNAL, QByteArray(), mainKitGenerator.toUtf8())); if (!extraKitGenerator.isEmpty()) @@ -183,8 +157,8 @@ void BuildDirManager::maybeForceReparseOnceReaderReady() if (ccit->key == kcit->key) { if (ccit->value != kcit->value) { if (criticalKeys.contains(kcit->key)) { - clearCache(); - return; + clearCache(); + return false; // no need to trigger a new reader, clearCache will do that } mustReparse = true; } @@ -204,8 +178,7 @@ void BuildDirManager::maybeForceReparseOnceReaderReady() // // The critical keys *must* be set in cmake configuration, so those were already // handled above. - if (mustReparse || kcit != targetConfig.constEnd()) - emit requestReparse(true); + return mustReparse || kcit != targetConfig.constEnd(); } bool BuildDirManager::isParsing() const @@ -213,104 +186,113 @@ bool BuildDirManager::isParsing() const return m_reader && m_reader->isParsing(); } -void BuildDirManager::becameDirty() +void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters ¶meters, + int newReaderReparseOptions, + int existingReaderReparseOptions) { - if (isParsing()) - return; + QTC_ASSERT(parameters.isValid(), return); - Target *t = m_buildConfiguration->target()->project()->activeTarget(); - BuildConfiguration *bc = t ? t->activeBuildConfiguration() : nullptr; + if (m_reader) + m_reader->stop(); - if (bc != m_buildConfiguration) - return; + BuildDirReader *old = m_reader.get(); - const CMakeTool *tool = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit()); - if (!tool->isAutoRun()) - return; - - emit requestReparse(false); -} + m_parameters = parameters; + m_parameters.buildDirectory = workDirectory(parameters); -void BuildDirManager::forceReparse() -{ - forceReparseImpl(true); + updateReaderType(m_parameters, + [this, old, newReaderReparseOptions, existingReaderReparseOptions]() { + if (old != m_reader.get()) + emit requestReparse(newReaderReparseOptions); + else + emit requestReparse(existingReaderReparseOptions); + }); } -void BuildDirManager::forceReparseWithoutCheckingForChanges() +CMakeBuildConfiguration *BuildDirManager::buildConfiguration() const { - forceReparseImpl(false); + return m_parameters.buildConfiguration; } -void BuildDirManager::forceReparseImpl(bool checkForChanges) +void BuildDirManager::becameDirty() { - QTC_ASSERT(!m_isHandlingError, return); + if (isParsing()) + return; - if (m_buildConfiguration->target()->activeBuildConfiguration() != m_buildConfiguration) + if (!m_parameters.buildConfiguration || !m_parameters.buildConfiguration->isActive()) return; - CMakeTool *tool = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit()); - QTC_ASSERT(tool, return); + const CMakeTool *tool = m_parameters.cmakeTool; + if (!tool->isAutoRun()) + return; - m_reader.reset(); // Force reparse by forcing in a new reader - updateReaderType([this, checkForChanges]() { parseOnceReaderReady(true, checkForChanges); }); + emit requestReparse(REPARSE_CHECK_CONFIGURATION); } void BuildDirManager::resetData() { - QTC_ASSERT(!m_isHandlingError, return); - if (m_reader) m_reader->resetData(); - - m_cmakeCache.clear(); - m_reader.reset(); - - m_buildTargets.clear(); } bool BuildDirManager::persistCMakeState() { + QTC_ASSERT(m_parameters.isValid(), return false); + if (!m_tempDir) return false; - const QString buildDir = m_buildConfiguration->buildDirectory().toString(); - QDir dir(buildDir); - dir.mkpath(buildDir); + const Utils::FileName buildDir = m_parameters.buildDirectory; + QDir dir(buildDir.toString()); + dir.mkpath(buildDir.toString()); m_tempDir.reset(nullptr); - QTimer::singleShot(0, this, &BuildDirManager::parse); // make sure signals only happen afterwards! + emit requestReparse(REPARSE_URGENT | REPARSE_FORCE_CONFIGURATION | REPARSE_CHECK_CONFIGURATION); return true; } -void BuildDirManager::generateProjectTree(CMakeProjectNode *root, const QList<const FileNode *> &allFiles) +void BuildDirManager::parse(int reparseParameters) { - QTC_ASSERT(!m_isHandlingError, return); + QTC_ASSERT(m_parameters.isValid(), return); QTC_ASSERT(m_reader, return); + QTC_ASSERT((reparseParameters & REPARSE_FAIL) == 0, return); + QTC_ASSERT((reparseParameters & REPARSE_IGNORE) == 0, return); - const Utils::FileName projectFile = m_buildConfiguration->target()->project()->projectFilePath(); + m_reader->stop(); - m_reader->generateProjectTree(root, allFiles); + TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); + + if (reparseParameters & REPARSE_CHECK_CONFIGURATION) { + if (checkConfiguration()) + reparseParameters |= REPARSE_FORCE_CONFIGURATION; + } + + m_reader->parse(reparseParameters & REPARSE_FORCE_CONFIGURATION); } -void BuildDirManager::updateCodeModel(CppTools::RawProjectParts &rpps) +void BuildDirManager::generateProjectTree(CMakeProjectNode *root, const QList<const FileNode *> &allFiles) const { QTC_ASSERT(!m_isHandlingError, return); QTC_ASSERT(m_reader, return); - return m_reader->updateCodeModel(rpps); + + m_reader->generateProjectTree(root, allFiles); } -void BuildDirManager::parse() +void BuildDirManager::updateCodeModel(CppTools::RawProjectParts &rpps) { - updateReaderType([this]() { parseOnceReaderReady(false); }); + QTC_ASSERT(!m_isHandlingError, return); + QTC_ASSERT(m_reader, return); + return m_reader->updateCodeModel(rpps); } void BuildDirManager::clearCache() { + QTC_ASSERT(m_parameters.isValid(), return); QTC_ASSERT(!m_isHandlingError, return); - auto cmakeCache = Utils::FileName(workDirectory()).appendPath(QLatin1String("CMakeCache.txt")); - auto cmakeFiles = Utils::FileName(workDirectory()).appendPath(QLatin1String("CMakeFiles")); + auto cmakeCache = workDirectory(m_parameters).appendPath("CMakeCache.txt"); + auto cmakeFiles = workDirectory(m_parameters).appendPath("CMakeFiles"); const bool mustCleanUp = cmakeCache.exists() || cmakeFiles.exists(); if (!mustCleanUp) @@ -319,7 +301,7 @@ void BuildDirManager::clearCache() Utils::FileUtils::removeRecursively(cmakeCache); Utils::FileUtils::removeRecursively(cmakeFiles); - forceReparse(); + m_reader.reset(); } static CMakeBuildTarget utilityTarget(const QString &title, const BuildDirManager *bdm) @@ -334,44 +316,41 @@ static CMakeBuildTarget utilityTarget(const QString &title, const BuildDirManage return target; } -QList<CMakeBuildTarget> BuildDirManager::buildTargets() const +QList<CMakeBuildTarget> BuildDirManager::takeBuildTargets() const { - QTC_ASSERT(!m_isHandlingError, return {}); - - if (!m_reader) - return QList<CMakeBuildTarget>(); - if (m_buildTargets.isEmpty()) { - m_buildTargets.append(utilityTarget(CMakeBuildStep::allTarget(), this)); - m_buildTargets.append(utilityTarget(CMakeBuildStep::cleanTarget(), this)); - m_buildTargets.append(utilityTarget(CMakeBuildStep::installTarget(), this)); - m_buildTargets.append(utilityTarget(CMakeBuildStep::testTarget(), this)); - - m_buildTargets.append(Utils::filtered(m_reader->buildTargets(), [](const CMakeBuildTarget &bt) { + QList<CMakeBuildTarget> result = { utilityTarget(CMakeBuildStep::allTarget(), this), + utilityTarget(CMakeBuildStep::cleanTarget(), this), + utilityTarget(CMakeBuildStep::installTarget(), this), + utilityTarget(CMakeBuildStep::testTarget(), this) }; + QTC_ASSERT(!m_isHandlingError, return result); + + if (m_reader) { + result.append(Utils::filtered(m_reader->takeBuildTargets(), [](const CMakeBuildTarget &bt) { return bt.title != CMakeBuildStep::allTarget() && bt.title != CMakeBuildStep::cleanTarget() && bt.title != CMakeBuildStep::installTarget() && bt.title != CMakeBuildStep::testTarget(); })); } - return m_buildTargets; + return result; } -CMakeConfig BuildDirManager::parsedConfiguration() const +CMakeConfig BuildDirManager::takeCMakeConfiguration() const { QTC_ASSERT(!m_isHandlingError, return {}); if (!m_reader) - return m_cmakeCache; - if (m_cmakeCache.isEmpty()) - m_cmakeCache = m_reader->takeParsedConfiguration(); + return CMakeConfig(); - for (auto &ci : m_cmakeCache) + CMakeConfig result = m_reader->takeParsedConfiguration(); + for (auto &ci : result) ci.inCMakeCache = true; - return m_cmakeCache; + return result; } -CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile, QString *errorMessage) +CMakeConfig BuildDirManager::parseCMakeConfiguration(const Utils::FileName &cacheFile, + QString *errorMessage) { if (!cacheFile.exists()) { if (errorMessage) @@ -384,25 +363,26 @@ CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile return result; } -void BuildDirManager::checkConfiguration() +bool BuildDirManager::checkConfiguration() { + QTC_ASSERT(m_parameters.isValid(), return false); + if (m_tempDir) // always throw away changes in the tmpdir! - return; + return false; - Kit *k = m_buildConfiguration->target()->kit(); - const CMakeConfig cache = parsedConfiguration(); + const CMakeConfig cache = m_parameters.buildConfiguration->configurationFromCMake(); if (cache.isEmpty()) - return; // No cache file yet. + return false; // No cache file yet. CMakeConfig newConfig; QSet<QString> changedKeys; QSet<QString> removedKeys; - foreach (const CMakeConfigItem &iBc, m_buildConfiguration->cmakeConfiguration()) { + foreach (const CMakeConfigItem &iBc, m_parameters.configuration) { const CMakeConfigItem &iCache = Utils::findOrDefault(cache, [&iBc](const CMakeConfigItem &i) { return i.key == iBc.key; }); if (iCache.isNull()) { removedKeys << QString::fromUtf8(iBc.key); - } else if (QString::fromUtf8(iCache.value) != iBc.expandedValue(k)) { + } else if (QString::fromUtf8(iCache.value) != iBc.expandedValue(m_parameters.expander)) { changedKeys << QString::fromUtf8(iBc.key); newConfig.append(iCache); } else { @@ -435,22 +415,15 @@ void BuildDirManager::checkConfiguration() box->setDefaultButton(defaultButton); box->exec(); - if (box->clickedButton() == applyButton) - m_buildConfiguration->setCMakeConfiguration(newConfig); + if (box->clickedButton() == applyButton) { + m_parameters.configuration = newConfig; + QSignalBlocker blocker(m_parameters.buildConfiguration); + m_parameters.buildConfiguration->setConfigurationForCMake(newConfig); + return false; + } else if (box->clickedButton() == defaultButton) + return true; } -} - -void BuildDirManager::maybeForceReparse() -{ - if (m_isHandlingError) - return; - - if (!m_reader || !m_reader->hasData()) { - emit requestReparse(true); - return; - } - - updateReaderType([this]() { maybeForceReparseOnceReaderReady(); }); + return false; } } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index 4db167d042..e1762fc461 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -25,9 +25,13 @@ #pragma once +#include "builddirparameters.h" #include "builddirreader.h" +#include "cmakebuildtarget.h" #include "cmakeconfigitem.h" +#include <cpptools/cpprawprojectpart.h> + #include <utils/fileutils.h> #include <utils/temporarydirectory.h> @@ -37,12 +41,7 @@ #include <functional> #include <memory> -namespace ProjectExplorer { -class FileNode; -class IOutputParser; -class Kit; -class Task; -} // namespace ProjectExplorer +namespace ProjectExplorer { class FileNode; } namespace CMakeProjectManager { @@ -50,6 +49,7 @@ class CMakeTool; namespace Internal { +class CMakeProjectNode; class CMakeBuildConfiguration; class BuildDirManager : public QObject @@ -57,61 +57,63 @@ class BuildDirManager : public QObject Q_OBJECT public: - BuildDirManager(CMakeBuildConfiguration *bc); + BuildDirManager(); ~BuildDirManager() final; bool isParsing() const; + void setParametersAndRequestParse(const BuildDirParameters ¶meters, + int newReaderReparseOptions, int existingReaderReparseOptions); + CMakeBuildConfiguration *buildConfiguration() const; + void clearCache(); - void forceReparse(); - void forceReparseWithoutCheckingForChanges(); - void maybeForceReparse(); // Only reparse if the configuration has changed... + void resetData(); bool persistCMakeState(); + void parse(int reparseParameters); + void generateProjectTree(CMakeProjectNode *root, - const QList<const ProjectExplorer::FileNode *> &allFiles); + const QList<const ProjectExplorer::FileNode *> &allFiles) const; void updateCodeModel(CppTools::RawProjectParts &rpps); - QList<CMakeBuildTarget> buildTargets() const; - CMakeConfig parsedConfiguration() const; + QList<CMakeBuildTarget> takeBuildTargets() const; + CMakeConfig takeCMakeConfiguration() const; - static CMakeConfig parseConfiguration(const Utils::FileName &cacheFile, - QString *errorMessage); + static CMakeConfig parseCMakeConfiguration(const Utils::FileName &cacheFile, + QString *errorMessage); - CMakeBuildConfiguration *buildConfiguration() const { return m_buildConfiguration; } + enum ReparseParameters { REPARSE_DEFAULT = 0, // use defaults + REPARSE_URGENT = 1, // Do not wait for more requests, start ASAP + REPARSE_FORCE_CONFIGURATION = 2, // Force configuration arguments to cmake + REPARSE_CHECK_CONFIGURATION = 4, // Check and warn if on-disk config and QtC config differ + REPARSE_IGNORE = 8, // Do not reparse:-) + REPARSE_FAIL = 16 // Do not reparse and raise a warning + }; signals: - void requestReparse(bool urgent) const; - void configurationStarted() const; + void requestReparse(int reparseParameters) const; + void parsingStarted() const; void dataAvailable() const; void errorOccured(const QString &err) const; private: void emitDataAvailable(); void emitErrorOccured(const QString &message) const; - void checkConfiguration(); + bool checkConfiguration(); - const Utils::FileName workDirectory() const; + Utils::FileName workDirectory(const BuildDirParameters ¶meters) const; - void updateReaderType(std::function<void()> todo); - void updateReaderData(); + void updateReaderType(const BuildDirParameters &p, std::function<void()> todo); - void forceReparseImpl(bool checkForChanges); - void parseOnceReaderReady(bool force, bool checkForChanges = true); - void maybeForceReparseOnceReaderReady(); + bool hasConfigChanged(); - void parse(); void becameDirty(); - CMakeBuildConfiguration *m_buildConfiguration = nullptr; + BuildDirParameters m_parameters; mutable std::unique_ptr<Utils::TemporaryDirectory> m_tempDir = nullptr; - mutable CMakeConfig m_cmakeCache; - - std::unique_ptr<BuildDirReader> m_reader; - - mutable QList<CMakeBuildTarget> m_buildTargets; + mutable std::unique_ptr<BuildDirReader> m_reader; mutable bool m_isHandlingError = false; }; diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.cpp b/src/plugins/cmakeprojectmanager/builddirparameters.cpp new file mode 100644 index 0000000000..4af170b490 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/builddirparameters.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "builddirparameters.h" + +#include "cmakebuildconfiguration.h" +#include "cmakekitinformation.h" + +#include <projectexplorer/kit.h> +#include <projectexplorer/kitinformation.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/target.h> + +using namespace ProjectExplorer; + +namespace CMakeProjectManager { +namespace Internal { + +BuildDirParameters::BuildDirParameters() = default; + +BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc) +{ + buildConfiguration = bc; + + const Kit *k = bc->target()->kit(); + + projectName = bc->target()->project()->displayName(); + + sourceDirectory = bc->target()->project()->projectDirectory(); + buildDirectory = bc->buildDirectory(); + + environment = bc->environment(); + + cmakeTool = CMakeKitInformation::cmakeTool(k); + + auto tc = ToolChainKitInformation::toolChain(k, Constants::CXX_LANGUAGE_ID); + if (tc) + cxxToolChainId = tc->id(); + tc = ToolChainKitInformation::toolChain(k, Constants::C_LANGUAGE_ID); + if (tc) + cToolChainId = tc->id(); + sysRoot = SysRootKitInformation::sysRoot(k); + + expander = k->macroExpander(); + + configuration = bc->configurationForCMake(); + + generator = CMakeGeneratorKitInformation::generator(k); + extraGenerator = CMakeGeneratorKitInformation::extraGenerator(k); + platform = CMakeGeneratorKitInformation::platform(k); + toolset = CMakeGeneratorKitInformation::toolset(k); + generatorArguments = CMakeGeneratorKitInformation::generatorArguments(k); +} + +bool BuildDirParameters::isValid() const { return buildConfiguration && cmakeTool; } + +BuildDirParameters::BuildDirParameters(const BuildDirParameters &) = default; + +} // namespace Internal +} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.h b/src/plugins/cmakeprojectmanager/builddirparameters.h new file mode 100644 index 0000000000..08056085ee --- /dev/null +++ b/src/plugins/cmakeprojectmanager/builddirparameters.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "cmakeconfigitem.h" +#include "cmaketool.h" + +#include <utils/environment.h> +#include <utils/fileutils.h> +#include <utils/macroexpander.h> + +#include <QString> + +namespace CMakeProjectManager { +namespace Internal { + +class CMakeBuildConfiguration; + +class BuildDirParameters { +public: + BuildDirParameters(); + BuildDirParameters(CMakeBuildConfiguration *bc); + BuildDirParameters(const BuildDirParameters &other); + + bool isValid() const; + + CMakeBuildConfiguration *buildConfiguration = nullptr; + QString projectName; + + Utils::FileName sourceDirectory; + Utils::FileName buildDirectory; + Utils::Environment environment; + CMakeTool *cmakeTool = nullptr; + + QByteArray cxxToolChainId; + QByteArray cToolChainId; + + Utils::FileName sysRoot; + + Utils::MacroExpander *expander = nullptr; + + CMakeConfig configuration; + + QString generator; + QString extraGenerator; + QString platform; + QString toolset; + QStringList generatorArguments; +}; + +} // namespace Internal +} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/builddirreader.cpp b/src/plugins/cmakeprojectmanager/builddirreader.cpp index 2d0ce4c815..1d15eb7f7f 100644 --- a/src/plugins/cmakeprojectmanager/builddirreader.cpp +++ b/src/plugins/cmakeprojectmanager/builddirreader.cpp @@ -25,14 +25,10 @@ #include "builddirreader.h" -#include "cmakebuildconfiguration.h" -#include "cmakekitinformation.h" #include "servermodereader.h" #include "tealeafreader.h" -#include <projectexplorer/kitinformation.h> -#include <projectexplorer/projectexplorerconstants.h> -#include <projectexplorer/target.h> +#include <utils/qtcassert.h> using namespace ProjectExplorer; @@ -43,57 +39,15 @@ namespace Internal { // BuildDirReader: // -------------------------------------------------------------------- -BuildDirReader::Parameters::Parameters() = default; - -BuildDirReader::Parameters::Parameters(const CMakeBuildConfiguration *bc) -{ - const ProjectExplorer::Kit *k = bc->target()->kit(); - - projectName = bc->target()->project()->displayName(); - - sourceDirectory = bc->target()->project()->projectDirectory(); - buildDirectory = bc->buildDirectory(); - - environment = bc->environment(); - - CMakeTool *cmake = CMakeKitInformation::cmakeTool(k); - cmakeVersion = cmake->version(); - cmakeHasServerMode = cmake->hasServerMode(); - cmakeExecutable = cmake->cmakeExecutable(); - - pathMapper = cmake->pathMapper(); - isAutorun = cmake->isAutoRun(); - - auto tc = ProjectExplorer::ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); - if (tc) - cxxToolChainId = tc->id(); - tc = ProjectExplorer::ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::C_LANGUAGE_ID); - if (tc) - cToolChainId = tc->id(); - sysRoot = ProjectExplorer::SysRootKitInformation::sysRoot(k); - - expander = k->macroExpander(); - - configuration = bc->cmakeConfiguration(); - - generator = CMakeGeneratorKitInformation::generator(k); - extraGenerator = CMakeGeneratorKitInformation::extraGenerator(k); - platform = CMakeGeneratorKitInformation::platform(k); - toolset = CMakeGeneratorKitInformation::toolset(k); - generatorArguments = CMakeGeneratorKitInformation::generatorArguments(k); -} - -BuildDirReader::Parameters::Parameters(const BuildDirReader::Parameters &) = default; - - -BuildDirReader *BuildDirReader::createReader(const BuildDirReader::Parameters &p) +BuildDirReader *BuildDirReader::createReader(const BuildDirParameters &p) { - if (p.cmakeHasServerMode) + QTC_ASSERT(p.isValid() && p.cmakeTool, return nullptr); + if (p.cmakeTool->hasServerMode()) return new ServerModeReader; return new TeaLeafReader; } -void BuildDirReader::setParameters(const BuildDirReader::Parameters &p) +void BuildDirReader::setParameters(const BuildDirParameters &p) { m_parameters = p; } diff --git a/src/plugins/cmakeprojectmanager/builddirreader.h b/src/plugins/cmakeprojectmanager/builddirreader.h index 42630c5e13..e10109701d 100644 --- a/src/plugins/cmakeprojectmanager/builddirreader.h +++ b/src/plugins/cmakeprojectmanager/builddirreader.h @@ -25,8 +25,9 @@ #pragma once +#include "builddirparameters.h" +#include "cmakebuildtarget.h" #include "cmakeconfigitem.h" -#include "cmakeproject.h" #include "cmaketool.h" #include <cpptools/cpprawprojectpart.h> @@ -38,6 +39,8 @@ #include <QFutureInterface> #include <QObject> +namespace ProjectExplorer { class FileNode; } + namespace CMakeProjectManager { namespace Internal { @@ -49,52 +52,19 @@ class BuildDirReader : public QObject Q_OBJECT public: - struct Parameters { - Parameters(); - Parameters(const CMakeBuildConfiguration *bc); - Parameters(const Parameters &other); - - QString projectName; - - Utils::FileName sourceDirectory; - Utils::FileName buildDirectory; - Utils::Environment environment; - Utils::FileName cmakeExecutable; - CMakeTool::Version cmakeVersion; - bool cmakeHasServerMode = false; - CMakeTool::PathMapper pathMapper; - - QByteArray cxxToolChainId; - QByteArray cToolChainId; - - Utils::FileName sysRoot; - - Utils::MacroExpander *expander = nullptr; - - CMakeConfig configuration; - - QString generator; - QString extraGenerator; - QString platform; - QString toolset; - QStringList generatorArguments; - bool isAutorun = false; - }; - - static BuildDirReader *createReader(const BuildDirReader::Parameters &p); - virtual void setParameters(const Parameters &p); + static BuildDirReader *createReader(const BuildDirParameters &p); + virtual void setParameters(const BuildDirParameters &p); - virtual bool isCompatible(const Parameters &p) = 0; + virtual bool isCompatible(const BuildDirParameters &p) = 0; virtual void resetData() = 0; - virtual void parse(bool force) = 0; + virtual void parse(bool forceConfiguration) = 0; virtual void stop() = 0; virtual bool isReady() const { return true; } virtual bool isParsing() const = 0; - virtual bool hasData() const = 0; + virtual QList<CMakeBuildTarget> takeBuildTargets() = 0; virtual CMakeConfig takeParsedConfiguration() = 0; - virtual QList<CMakeBuildTarget> buildTargets() const = 0; virtual void generateProjectTree(CMakeProjectNode *root, const QList<const ProjectExplorer::FileNode *> &allFiles) = 0; virtual void updateCodeModel(CppTools::RawProjectParts &rpps) = 0; @@ -107,7 +77,7 @@ signals: void errorOccured(const QString &message) const; protected: - Parameters m_parameters; + BuildDirParameters m_parameters; }; } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index a62fa7f4af..f707e2ef2b 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -64,17 +64,11 @@ const char INITIAL_ARGUMENTS[] = "CMakeProjectManager.CMakeBuildConfiguration.In const char CONFIGURATION_KEY[] = "CMake.Configuration"; CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent) : - BuildConfiguration(parent, Core::Id(Constants::CMAKE_BC_ID)), - m_buildDirManager(new BuildDirManager(this)) + BuildConfiguration(parent, Core::Id(Constants::CMAKE_BC_ID)) { ctor(); } -CMakeBuildConfiguration::~CMakeBuildConfiguration() -{ - m_buildDirManager->deleteLater(); // Do not block while waiting for cmake... -} - bool CMakeBuildConfiguration::isEnabled() const { return m_error.isEmpty() && !isParsing(); @@ -88,8 +82,7 @@ QString CMakeBuildConfiguration::disabledReason() const CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent, CMakeBuildConfiguration *source) : BuildConfiguration(parent, source), - m_configuration(source->m_configuration), - m_buildDirManager(new BuildDirManager(this)) + m_configurationForCMake(source->m_configurationForCMake) { ctor(); cloneSteps(source); @@ -99,7 +92,7 @@ QVariantMap CMakeBuildConfiguration::toMap() const { QVariantMap map(ProjectExplorer::BuildConfiguration::toMap()); const QStringList config - = Utils::transform(m_configuration, [](const CMakeConfigItem &i) { return i.toString(); }); + = Utils::transform(m_configurationForCMake, [](const CMakeConfigItem &i) { return i.toString(); }); map.insert(QLatin1String(CONFIGURATION_KEY), config); return map; } @@ -130,110 +123,28 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map) } // End Legacy - setCMakeConfiguration(legacyConf + conf); + setConfigurationForCMake(legacyConf + conf); return true; } void CMakeBuildConfiguration::ctor() { - auto project = static_cast<CMakeProject *>(target()->project()); - setBuildDirectory(shadowBuildDirectory(project->projectFilePath(), + auto p = static_cast<CMakeProject *>(project()); + setBuildDirectory(shadowBuildDirectory(p->projectFilePath(), target()->kit(), displayName(), BuildConfiguration::Unknown)); - - connect(m_buildDirManager.get(), &BuildDirManager::requestReparse, - this, [this](bool urgent) { emit requestReparse(this, urgent); }); - connect(m_buildDirManager.get(), &BuildDirManager::dataAvailable, - this, [this, project]() { - clearError(); - project->handleParsingSuccess(this); - }); - connect(m_buildDirManager.get(), &BuildDirManager::errorOccured, - this, [this, project](const QString &msg) { - setError(msg); - project->handleParsingError(this); - }); - connect(m_buildDirManager.get(), &BuildDirManager::configurationStarted, - this, [this]() { - clearError(ForceEnabledChanged::True); - emit parsingStarted(this); - }); - - connect(this, &CMakeBuildConfiguration::environmentChanged, - m_buildDirManager.get(), &BuildDirManager::forceReparse); - connect(this, &CMakeBuildConfiguration::buildDirectoryChanged, - m_buildDirManager.get(), &BuildDirManager::forceReparse); -} - -void CMakeBuildConfiguration::maybeForceReparse() -{ - clearError(); - m_buildDirManager->maybeForceReparse(); + connect(p, &Project::parsingFinished, this, &BuildConfiguration::enabledChanged); } bool CMakeBuildConfiguration::isParsing() const { - return m_buildDirManager && m_buildDirManager->isParsing(); -} - -void CMakeBuildConfiguration::resetData() -{ - clearError(); - m_buildDirManager->resetData(); -} - -bool CMakeBuildConfiguration::persistCMakeState() -{ - return m_buildDirManager->persistCMakeState(); -} - -bool CMakeBuildConfiguration::updateCMakeStateBeforeBuild() -{ - return static_cast<CMakeProject *>(project())->mustUpdateCMakeStateBeforeBuild(); -} - -void CMakeBuildConfiguration::runCMake() -{ - if (!m_buildDirManager || m_buildDirManager->isParsing()) - return; - - clearError(); - m_buildDirManager->forceReparse(); -} - -void CMakeBuildConfiguration::clearCache() -{ - if (m_buildDirManager) - m_buildDirManager->clearCache(); + return project()->isParsing() && isActive(); } QList<CMakeBuildTarget> CMakeBuildConfiguration::buildTargets() const { - if (!m_buildDirManager || m_buildDirManager->isParsing()) - return QList<CMakeBuildTarget>(); - - return m_buildDirManager->buildTargets(); -} - -CMakeProjectNode * -CMakeBuildConfiguration::generateProjectTree(const QList<const FileNode*> &allFiles) const -{ - if (!m_buildDirManager || m_buildDirManager->isParsing()) - return nullptr; - - auto root = new CMakeProjectNode(target()->project()->projectDirectory()); - m_buildDirManager->generateProjectTree(root, allFiles); - if (root->isEmpty()) { - delete root; - return nullptr; - } - return root; -} - -void CMakeBuildConfiguration::updateCodeModel(CppTools::RawProjectParts &rpps) -{ - m_buildDirManager->updateCodeModel(rpps); + return m_buildTargets; } FileName CMakeBuildConfiguration::shadowBuildDirectory(const FileName &projectFilePath, @@ -273,50 +184,23 @@ void CMakeBuildConfiguration::buildTarget(const QString &buildTarget) cmBs->setBuildTarget(originalBuildTarget); } -QList<ConfigModel::DataItem> CMakeBuildConfiguration::completeCMakeConfiguration() const +CMakeConfig CMakeBuildConfiguration::configurationFromCMake() const { - if (!m_buildDirManager || m_buildDirManager->isParsing()) - return QList<ConfigModel::DataItem>(); - - return Utils::transform(m_buildDirManager->parsedConfiguration(), - [](const CMakeConfigItem &i) { - ConfigModel::DataItem j; - j.key = QString::fromUtf8(i.key); - j.value = QString::fromUtf8(i.value); - j.description = QString::fromUtf8(i.documentation); - j.values = i.values; - j.inCMakeCache = i.inCMakeCache; - - j.isAdvanced = i.isAdvanced; - j.isHidden = i.type == CMakeConfigItem::INTERNAL || i.type == CMakeConfigItem::STATIC; - - switch (i.type) { - case CMakeConfigItem::FILEPATH: - j.type = ConfigModel::DataItem::FILE; - break; - case CMakeConfigItem::PATH: - j.type = ConfigModel::DataItem::DIRECTORY; - break; - case CMakeConfigItem::BOOL: - j.type = ConfigModel::DataItem::BOOLEAN; - break; - case CMakeConfigItem::STRING: - j.type = ConfigModel::DataItem::STRING; - break; - default: - j.type = ConfigModel::DataItem::UNKNOWN; - break; - } + return m_configurationFromCMake; +} - return j; - }); +void CMakeBuildConfiguration::setConfigurationFromCMake(const CMakeConfig &config) +{ + m_configurationFromCMake = config; } -void CMakeBuildConfiguration::setCurrentCMakeConfiguration(const QList<ConfigModel::DataItem> &items) +void CMakeBuildConfiguration::setBuildTargets(const QList<CMakeBuildTarget> &targets) { - if (!m_buildDirManager || m_buildDirManager->isParsing()) - return; + m_buildTargets = targets; +} +void CMakeBuildConfiguration::setConfigurationForCMake(const QList<ConfigModel::DataItem> &items) +{ const CMakeConfig newConfig = Utils::transform(items, [](const ConfigModel::DataItem &i) { CMakeConfigItem ni; ni.key = i.key.toUtf8(); @@ -346,10 +230,8 @@ void CMakeBuildConfiguration::setCurrentCMakeConfiguration(const QList<ConfigMod return ni; }); - const CMakeConfig config = cmakeConfiguration() + newConfig; - setCMakeConfiguration(config); - - m_buildDirManager->forceReparseWithoutCheckingForChanges(); + const CMakeConfig config = configurationForCMake() + newConfig; + setConfigurationForCMake(config); } void CMakeBuildConfiguration::clearError(ForceEnabledChanged fec) @@ -383,14 +265,14 @@ static CMakeConfig removeDuplicates(const CMakeConfig &config) return result; } -void CMakeBuildConfiguration::setCMakeConfiguration(const CMakeConfig &config) +void CMakeBuildConfiguration::setConfigurationForCMake(const CMakeConfig &config) { - m_configuration = removeDuplicates(config); + m_configurationForCMake = removeDuplicates(config); const Kit *k = target()->kit(); CMakeConfig kitConfig = CMakeConfigurationKitInformation::configuration(k); bool hasKitOverride = false; - foreach (const CMakeConfigItem &i, m_configuration) { + foreach (const CMakeConfigItem &i, m_configurationForCMake) { const QString b = CMakeConfigItem::expandedValueOf(k, i.key, kitConfig); if (!b.isNull() && i.expandedValue(k) != b) { hasKitOverride = true; @@ -402,11 +284,13 @@ void CMakeBuildConfiguration::setCMakeConfiguration(const CMakeConfig &config) setWarning(tr("CMake configuration set by the kit was overridden in the project.")); else setWarning(QString()); + + emit configurationForCMakeChanged(); } -CMakeConfig CMakeBuildConfiguration::cmakeConfiguration() const +CMakeConfig CMakeBuildConfiguration::configurationForCMake() const { - return removeDuplicates(CMakeConfigurationKitInformation::configuration(target()->kit()) + m_configuration); + return removeDuplicates(CMakeConfigurationKitInformation::configuration(target()->kit()) + m_configurationForCMake); } void CMakeBuildConfiguration::setError(const QString &message) @@ -528,9 +412,9 @@ QList<ProjectExplorer::BuildInfo *> CMakeBuildConfigurationFactory::availableSet ProjectExplorer::BuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer::Target *parent, const ProjectExplorer::BuildInfo *info) const { - QTC_ASSERT(info->factory() == this, return 0); - QTC_ASSERT(info->kitId == parent->kit()->id(), return 0); - QTC_ASSERT(!info->displayName.isEmpty(), return 0); + QTC_ASSERT(info->factory() == this, return nullptr); + QTC_ASSERT(info->kitId == parent->kit()->id(), return nullptr); + QTC_ASSERT(!info->displayName.isEmpty(), return nullptr); CMakeBuildInfo copy(*static_cast<const CMakeBuildInfo *>(info)); CMakeProject *project = static_cast<CMakeProject *>(parent->project()); @@ -556,7 +440,7 @@ ProjectExplorer::BuildConfiguration *CMakeBuildConfigurationFactory::create(Proj cleanSteps->insertStep(0, cleanStep); bc->setBuildDirectory(copy.buildDirectory); - bc->setCMakeConfiguration(copy.configuration); + bc->setConfigurationForCMake(copy.configuration); return bc; } @@ -571,7 +455,7 @@ bool CMakeBuildConfigurationFactory::canClone(const ProjectExplorer::Target *par CMakeBuildConfiguration *CMakeBuildConfigurationFactory::clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) { if (!canClone(parent, source)) - return 0; + return nullptr; auto old = static_cast<CMakeBuildConfiguration *>(source); return new CMakeBuildConfiguration(parent, old); } @@ -586,12 +470,11 @@ bool CMakeBuildConfigurationFactory::canRestore(const ProjectExplorer::Target *p CMakeBuildConfiguration *CMakeBuildConfigurationFactory::restore(ProjectExplorer::Target *parent, const QVariantMap &map) { if (!canRestore(parent, map)) - return 0; - auto bc = new CMakeBuildConfiguration(parent); + return nullptr; + auto bc = std::make_unique<CMakeBuildConfiguration>(parent); if (bc->fromMap(map)) - return bc; - delete bc; - return 0; + return bc.release(); + return nullptr; } bool CMakeBuildConfigurationFactory::canHandle(const ProjectExplorer::Target *t) const diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index 45a45ede73..df488bca32 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -52,11 +52,9 @@ class CMakeProjectNode; class CMakeBuildConfiguration : public ProjectExplorer::BuildConfiguration { Q_OBJECT - friend class CMakeBuildConfigurationFactory; public: CMakeBuildConfiguration(ProjectExplorer::Target *parent); - ~CMakeBuildConfiguration(); bool isEnabled() const override; QString disabledReason() const override; @@ -69,25 +67,13 @@ public: void emitBuildTypeChanged(); - void setCMakeConfiguration(const CMakeConfig &config); - bool hasCMakeConfiguration() const; - CMakeConfig cmakeConfiguration() const; + CMakeConfig configurationForCMake() const; + CMakeConfig configurationFromCMake() const; QString error() const; QString warning() const; - bool isParsing() const; - - void maybeForceReparse(); - void resetData(); - bool persistCMakeState(); - bool updateCMakeStateBeforeBuild(); - void runCMake(); - void clearCache(); - QList<CMakeBuildTarget> buildTargets() const; - CMakeProjectManager::Internal::CMakeProjectNode *generateProjectTree(const QList<const ProjectExplorer::FileNode *> &allFiles) const; - void updateCodeModel(CppTools::RawProjectParts &rpps); static Utils::FileName shadowBuildDirectory(const Utils::FileName &projectFilePath, const ProjectExplorer::Kit *k, @@ -97,12 +83,11 @@ public: void buildTarget(const QString &buildTarget); signals: - void requestReparse(CMakeBuildConfiguration *, bool isUrgent); - void parsingStarted(CMakeBuildConfiguration *); - void errorOccured(const QString &message); void warningOccured(const QString &message); + void configurationForCMakeChanged(); + protected: CMakeBuildConfiguration(ProjectExplorer::Target *parent, CMakeBuildConfiguration *source); bool fromMap(const QVariantMap &map) override; @@ -110,22 +95,30 @@ protected: private: void ctor(); + bool isParsing() const; + enum ForceEnabledChanged : quint8 { False, True }; void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False); - QList<ConfigModel::DataItem> completeCMakeConfiguration() const; - void setCurrentCMakeConfiguration(const QList<ConfigModel::DataItem> &items); + + void setBuildTargets(const QList<CMakeBuildTarget> &targets); + void setConfigurationFromCMake(const CMakeConfig &config); + void setConfigurationForCMake(const QList<ConfigModel::DataItem> &items); + void setConfigurationForCMake(const CMakeConfig &config); void setError(const QString &message); void setWarning(const QString &message); - CMakeConfig m_configuration; + CMakeConfig m_configurationForCMake; QString m_error; QString m_warning; - std::unique_ptr<BuildDirManager> m_buildDirManager; + CMakeConfig m_configurationFromCMake; + QList<CMakeBuildTarget> m_buildTargets; + friend class CMakeBuildConfigurationFactory; friend class CMakeBuildSettingsWidget; friend class CMakeProjectManager::CMakeProject; + friend class BuildDirManager; }; class CMakeProjectImporter; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildinfo.h b/src/plugins/cmakeprojectmanager/cmakebuildinfo.h index 45fc90594a..cbdae54808 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildinfo.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildinfo.h @@ -52,7 +52,7 @@ public: QTC_ASSERT(bc->target()->project(), return); sourceDirectory = bc->target()->project()->projectDirectory().toString(); - configuration = bc->cmakeConfiguration(); + configuration = bc->configurationForCMake(); } bool operator==(const BuildInfo &o) const final diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp index 8985a0799e..3dd52c0bed 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp @@ -227,13 +227,13 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) if (m_buildConfiguration->isParsing()) m_showProgressTimer.start(); else { - m_configModel->setConfiguration(m_buildConfiguration->completeCMakeConfiguration()); + m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake()); m_configView->expandAll(); } - connect(m_buildConfiguration->target()->project(), &ProjectExplorer::Project::parsingFinished, + connect(project, &ProjectExplorer::Project::parsingFinished, this, [this, buildDirChooser, stretcher]() { - m_configModel->setConfiguration(m_buildConfiguration->completeCMakeConfiguration()); + m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake()); m_configView->expandAll(); stretcher->stretch(); updateButtonState(); @@ -264,7 +264,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) connect(m_resetButton, &QPushButton::clicked, m_configModel, &ConfigModel::resetAllChanges); connect(m_reconfigureButton, &QPushButton::clicked, this, [this]() { - m_buildConfiguration->setCurrentCMakeConfiguration(m_configModel->configurationChanges()); + m_buildConfiguration->setConfigurationForCMake(m_configModel->configurationChanges()); }); connect(m_editButton, &QPushButton::clicked, this, [this]() { QModelIndex idx = m_configView->currentIndex(); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index 5eea51739d..616eb61e03 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -269,10 +269,11 @@ void CMakeBuildStep::run(QFutureInterface<bool> &fi) QTC_ASSERT(bc, return); bool mustDelay = false; - if (bc->persistCMakeState()) { + auto p = static_cast<CMakeProject *>(bc->project()); + if (p->persistCMakeState()) { emit addOutput(tr("Persisting CMake state..."), BuildStep::OutputFormat::NormalMessage); mustDelay = true; - } else if (bc->updateCMakeStateBeforeBuild()) { + } else if (p->mustUpdateCMakeStateBeforeBuild()) { emit addOutput(tr("Running CMake in preparation to build..."), BuildStep::OutputFormat::NormalMessage); mustDelay = true; } else { diff --git a/src/plugins/cmakeprojectmanager/cmakebuildtarget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildtarget.cpp new file mode 100644 index 0000000000..357f66f6a5 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/cmakebuildtarget.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "cmakebuildtarget.h" + +using namespace Utils; + +namespace CMakeProjectManager { + +void CMakeBuildTarget::clear() +{ + executable.clear(); + makeCommand.clear(); + workingDirectory.clear(); + sourceDirectory.clear(); + title.clear(); + targetType = UtilityType; + includeFiles.clear(); + compilerOptions.clear(); + macros.clear(); + files.clear(); +} + +} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h new file mode 100644 index 0000000000..1b3f5fb700 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "cmake_global.h" + +#include <projectexplorer/projectmacro.h> + +#include <utils/fileutils.h> + +#include <QStringList> + +namespace CMakeProjectManager { + +enum TargetType { + ExecutableType = 0, + StaticLibraryType = 2, + DynamicLibraryType = 3, + UtilityType = 64 +}; + +class CMAKE_EXPORT CMakeBuildTarget +{ +public: + QString title; + Utils::FileName executable; // TODO: rename to output? + TargetType targetType = UtilityType; + Utils::FileName workingDirectory; + Utils::FileName sourceDirectory; + Utils::FileName makeCommand; + + // code model + QList<Utils::FileName> includeFiles; + QStringList compilerOptions; + ProjectExplorer::Macros macros; + QList<Utils::FileName> files; + + void clear(); +}; + +} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 2ab0037bd0..5aac57556e 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -42,6 +42,7 @@ #include <projectexplorer/deploymentdata.h> #include <projectexplorer/headerpath.h> #include <projectexplorer/kitinformation.h> +#include <projectexplorer/kitmanager.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> #include <projectexplorer/toolchain.h> @@ -66,6 +67,11 @@ namespace CMakeProjectManager { using namespace Internal; +static CMakeBuildConfiguration *activeBc(const CMakeProject *p) +{ + return qobject_cast<CMakeBuildConfiguration *>(p->activeTarget() ? p->activeTarget()->activeBuildConfiguration() : nullptr); +} + // QtCreator CMake Generator wishlist: // Which make targets we need to build to get all executables // What is the actual compiler executable @@ -77,27 +83,129 @@ using namespace Internal; CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEMIMETYPE, fileName), m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { - m_delayedParsingTimer.setSingleShot(true); - - connect(&m_delayedParsingTimer, &QTimer::timeout, - this, [this]() { startParsingProject(PARSE); }); - setId(CMakeProjectManager::Constants::CMAKEPROJECT_ID); + setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); setDisplayName(projectDirectory().fileName()); - connect(this, &Project::activeProjectConfigurationChanged, - this, &CMakeProject::handleActiveProjectConfigurationChanged); + // Timer: + m_delayedParsingTimer.setSingleShot(true); - subscribeSignal(&CMakeBuildConfiguration::requestReparse, - this, [this](CMakeBuildConfiguration *bc, bool isUrgent) { - if (bc->isActive()) { - m_delayedParsingTimer.setInterval(isUrgent ? 0 : 1000); - m_delayedParsingTimer.start(); + connect(&m_delayedParsingTimer, &QTimer::timeout, + this, [this]() { startParsing(m_delayedParsingParameters); }); + + // BuildDirManager: + connect(&m_buildDirManager, &BuildDirManager::requestReparse, + this, &CMakeProject::handleReparseRequest); + connect(&m_buildDirManager, &BuildDirManager::dataAvailable, + this, [this]() { + CMakeBuildConfiguration *bc = activeBc(this); + if (bc && bc == m_buildDirManager.buildConfiguration()) { + bc->clearError(); + handleParsingSuccess(bc); } }); + connect(&m_buildDirManager, &BuildDirManager::errorOccured, + this, [this](const QString &msg) { + CMakeBuildConfiguration *bc = activeBc(this); + if (bc && bc == m_buildDirManager.buildConfiguration()) { + bc->setError(msg); + handleParsingError(bc); + } + }); + connect(&m_buildDirManager, &BuildDirManager::parsingStarted, + this, [this]() { + CMakeBuildConfiguration *bc = activeBc(this); + if (bc && bc == m_buildDirManager.buildConfiguration()) + bc->clearError(CMakeBuildConfiguration::ForceEnabledChanged::True); + }); + // Kit changed: + connect(KitManager::instance(), &KitManager::kitUpdated, + this, [this](Kit *k) { + CMakeBuildConfiguration *bc = activeBc(this); + if (!bc || k != bc->target()->kit()) + return; // not for us... + + // Build configuration has not changed, but Kit settings might have: + // reparse and check the configuration, independent of whether the reader has changed + m_buildDirManager.setParametersAndRequestParse( + BuildDirParameters(bc), + BuildDirManager::REPARSE_CHECK_CONFIGURATION, + BuildDirManager::REPARSE_CHECK_CONFIGURATION); + }); + + // Target switched: + connect(this, &Project::activeTargetChanged, this, [this]() { + CMakeBuildConfiguration *bc = activeBc(this); + + // Target has switched, so the kit has changed, too. + // * run cmake with configuration arguments if the reader needs to be switched + // * run cmake without configuration arguments if the reader stays + m_buildDirManager.setParametersAndRequestParse( + BuildDirParameters(bc), + BuildDirManager::REPARSE_CHECK_CONFIGURATION, + BuildDirManager::REPARSE_CHECK_CONFIGURATION); + }); + + // BuildConfiguration switched: + subscribeSignal(&Target::activeBuildConfigurationChanged, this, [this]() { + CMakeBuildConfiguration *bc = activeBc(this); + + // Build configuration has switched: + // * Error out if the reader updates, can not happen since all BCs share a target/kit. + // * run cmake without configuration arguments if the reader stays + m_buildDirManager.setParametersAndRequestParse( + BuildDirParameters(bc), + BuildDirManager::REPARSE_FAIL, + BuildDirManager::REPARSE_CHECK_CONFIGURATION); + }); + + // BuildConfiguration changed: + subscribeSignal(&CMakeBuildConfiguration::environmentChanged, this, [this]() { + auto senderBc = qobject_cast<CMakeBuildConfiguration *>(sender()); + + if (senderBc && senderBc->isActive()) { + // The environment on our BC has changed: + // * Error out if the reader updates, can not happen since all BCs share a target/kit. + // * run cmake without configuration arguments if the reader stays + m_buildDirManager.setParametersAndRequestParse( + BuildDirParameters(senderBc), + BuildDirManager::REPARSE_FAIL, + BuildDirManager::REPARSE_CHECK_CONFIGURATION); + } + }); + subscribeSignal(&CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() { + auto senderBc = qobject_cast<CMakeBuildConfiguration *>(sender()); + + if (senderBc && senderBc->isActive() && senderBc == m_buildDirManager.buildConfiguration()) { + // The build directory of our BC has changed: + // * Error out if the reader updates, can not happen since all BCs share a target/kit. + // * run cmake without configuration arguments if the reader stays + // If no configuration exists, then the arguments will get added automatically by + // the reader. + m_buildDirManager.setParametersAndRequestParse( + BuildDirParameters(senderBc), + BuildDirManager::REPARSE_FAIL, + BuildDirManager::REPARSE_CHECK_CONFIGURATION); + } + }); + subscribeSignal(&CMakeBuildConfiguration::configurationForCMakeChanged, this, [this]() { + auto senderBc = qobject_cast<CMakeBuildConfiguration *>(sender()); + + if (senderBc && senderBc->isActive() && senderBc == m_buildDirManager.buildConfiguration()) { + // The CMake configuration has changed on our BC: + // * Error out if the reader updates, can not happen since all BCs share a target/kit. + // * run cmake with configuration arguments if the reader stays + m_buildDirManager.setParametersAndRequestParse( + BuildDirParameters(senderBc), + BuildDirManager::REPARSE_FAIL, + BuildDirManager::REPARSE_FORCE_CONFIGURATION); + } + }); + + // TreeScanner: connect(&m_treeScanner, &TreeScanner::finished, this, &CMakeProject::handleTreeScanningFinished); m_treeScanner.setFilter([this](const Utils::MimeType &mimeType, const Utils::FileName &fn) { @@ -148,15 +256,19 @@ CMakeProject::~CMakeProject() void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) { - Target *const t = activeTarget(); + const CMakeBuildConfiguration *aBc = activeBc(this); QTC_ASSERT(bc, return); - QTC_ASSERT(bc == (t ? t->activeBuildConfiguration() : nullptr), return); - QTC_ASSERT(m_treeScanner.isFinished() && !bc->isParsing(), return); + QTC_ASSERT(bc == aBc, return); + QTC_ASSERT(m_treeScanner.isFinished() && !m_buildDirManager.isParsing(), return); + Target *t = bc->target(); Kit *k = t->kit(); - auto newRoot = bc->generateProjectTree(m_allFiles); + bc->setBuildTargets(m_buildDirManager.takeBuildTargets()); + bc->setConfigurationFromCMake(m_buildDirManager.takeCMakeConfiguration()); + + auto newRoot = generateProjectTree(m_allFiles); if (newRoot) { setDisplayName(newRoot->displayName()); setRootProjectNode(newRoot); @@ -184,7 +296,7 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) } CppTools::RawProjectParts rpps; - bc->updateCodeModel(rpps); + m_buildDirManager.updateCodeModel(rpps); for (CppTools::RawProjectPart &rpp : rpps) { // TODO: Set the Qt version only if target actually depends on Qt. @@ -197,6 +309,8 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) updateQmlJSCodeModel(); + m_buildDirManager.resetData(); + emit fileListChanged(); emit bc->emitBuildTypeChanged(); @@ -220,10 +334,10 @@ void CMakeProject::updateQmlJSCodeModel() if (!bc) return; - const QList<ConfigModel::DataItem> &cm = bc->completeCMakeConfiguration(); - foreach (const ConfigModel::DataItem &di, cm) { - if (di.key.contains(QStringLiteral("QML_IMPORT_PATH"))) { - cmakeImports = di.value; + const CMakeConfig &cm = bc->configurationFromCMake(); + foreach (const CMakeConfigItem &di, cm) { + if (di.key.contains("QML_IMPORT_PATH")) { + cmakeImports = QString::fromUtf8(di.value); break; } } @@ -234,6 +348,16 @@ void CMakeProject::updateQmlJSCodeModel() modelManager->updateProjectInfo(projectInfo, this); } +CMakeProjectNode *CMakeProject::generateProjectTree(const QList<const FileNode *> &allFiles) const +{ + if (m_buildDirManager.isParsing()) + return nullptr; + + auto root = std::make_unique<CMakeProjectNode>(projectDirectory()); + m_buildDirManager.generateProjectTree(root.get(), allFiles); + return root ? root.release() : nullptr; +} + bool CMakeProject::needsConfiguration() const { return targets().isEmpty(); @@ -264,53 +388,28 @@ void CMakeProject::runCMake() if (isParsing()) return; - startParsingProject(PARSE); + CMakeBuildConfiguration *bc = activeBc(this); + if (bc) { + BuildDirParameters parameters(bc); + m_buildDirManager.setParametersAndRequestParse(parameters, + BuildDirManager::REPARSE_CHECK_CONFIGURATION, + BuildDirManager::REPARSE_CHECK_CONFIGURATION); + } } void CMakeProject::runCMakeAndScanProjectTree() { - if (isParsing()) + if (!m_treeScanner.isFinished()) return; - startParsingProject(static_cast<DataCollectionAction>(PARSE | SCAN)); -} - -void CMakeProject::startParsingProject(const CMakeProject::DataCollectionAction action) -{ - const bool runParse = action & PARSE; - const bool runScan = action & SCAN; - - CMakeBuildConfiguration *bc = activeTarget() - ? qobject_cast<CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration()) - : nullptr; - if (!bc) - return; - - if (!m_treeScanner.isFinished() || m_waitingForScan) - return; - - emitParsingStarted(); - - m_waitingForParse = runParse; - m_waitingForScan = runScan; - m_combinedScanAndParseResult = true; - - if (runParse) - bc->runCMake(); - - if (runScan) { - m_treeScanner.asyncScanForFiles(projectDirectory()); - Core::ProgressManager::addTask(m_treeScanner.future(), - tr("Scan \"%1\" project tree").arg(displayName()), - "CMake.Scan.Tree"); - } + m_waitingForScan = true; + runCMake(); } void CMakeProject::buildCMakeTarget(const QString &buildTarget) { QTC_ASSERT(!buildTarget.isEmpty(), return); - Target *t = activeTarget(); - auto bc = qobject_cast<CMakeBuildConfiguration *>(t ? t->activeBuildConfiguration() : nullptr); + CMakeBuildConfiguration *bc = activeBc(this); if (bc) bc->buildTarget(buildTarget); } @@ -322,15 +421,60 @@ ProjectImporter *CMakeProject::projectImporter() const return m_projectImporter.get(); } +bool CMakeProject::persistCMakeState() +{ + return m_buildDirManager.persistCMakeState(); +} + +void CMakeProject::clearCMakeCache() +{ + m_buildDirManager.clearCache(); +} + QList<CMakeBuildTarget> CMakeProject::buildTargets() const { - CMakeBuildConfiguration *bc = nullptr; - if (activeTarget()) - bc = qobject_cast<CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration()); + CMakeBuildConfiguration *bc = activeBc(this); return bc ? bc->buildTargets() : QList<CMakeBuildTarget>(); } +void CMakeProject::handleReparseRequest(int reparseParameters) +{ + QTC_ASSERT(!(reparseParameters & BuildDirManager::REPARSE_FAIL), return); + if (reparseParameters & BuildDirManager::REPARSE_IGNORE) + return; + + m_delayedParsingTimer.setInterval((reparseParameters & BuildDirManager::REPARSE_URGENT) ? 0 : 1000); + m_delayedParsingTimer.start(); + m_delayedParsingParameters = m_delayedParsingParameters | reparseParameters; +} + +void CMakeProject::startParsing(int reparseParameters) +{ + m_delayedParsingParameters = BuildDirManager::REPARSE_DEFAULT; + + QTC_ASSERT((reparseParameters & BuildDirManager::REPARSE_FAIL) == 0, return); + if (reparseParameters & BuildDirManager::REPARSE_IGNORE) + return; + + QTC_ASSERT(activeBc(this), return); + + emitParsingStarted(); + + m_waitingForParse = true; + m_combinedScanAndParseResult = true; + + if (m_waitingForScan) { + QTC_CHECK(m_treeScanner.isFinished()); + m_treeScanner.asyncScanForFiles(projectDirectory()); + Core::ProgressManager::addTask(m_treeScanner.future(), + tr("Scan \"%1\" project tree").arg(displayName()), + "CMake.Scan.Tree"); + } + + m_buildDirManager.parse(reparseParameters); +} + QStringList CMakeProject::buildTargetTitles(bool runnable) const { const QList<CMakeBuildTarget> targets @@ -361,33 +505,9 @@ bool CMakeProject::setupTarget(Target *t) if (t->buildConfigurations().isEmpty()) return false; t->updateDefaultDeployConfigurations(); - return true; } -void CMakeProject::handleActiveProjectConfigurationChanged(ProjectConfiguration *pc) -{ - if (auto bc = qobject_cast<CMakeBuildConfiguration *>(pc)) { - if (!bc->isActive()) - return; - } else if (!qobject_cast<Target *>(pc)) { - return; - } - - for (Target *t : targets()) { - for (BuildConfiguration *bc : t->buildConfigurations()) { - auto i = qobject_cast<CMakeBuildConfiguration *>(bc); - QTC_ASSERT(i, continue); - if (i->isActive()) { - m_waitingForParse = true; - i->maybeForceReparse(); - } else { - i->resetData(); - } - } - } -} - void CMakeProject::handleTreeScanningFinished() { QTC_CHECK(m_waitingForScan); @@ -395,8 +515,7 @@ void CMakeProject::handleTreeScanningFinished() qDeleteAll(m_allFiles); m_allFiles = Utils::transform(m_treeScanner.release(), [](const FileNode *fn) { return fn; }); - auto t = activeTarget(); - auto bc = qobject_cast<CMakeBuildConfiguration*>(t ? t->activeBuildConfiguration() : nullptr); + CMakeBuildConfiguration *bc = activeBc(this); QTC_ASSERT(bc, return); m_combinedScanAndParseResult = m_combinedScanAndParseResult && true; @@ -407,7 +526,7 @@ void CMakeProject::handleTreeScanningFinished() void CMakeProject::handleParsingSuccess(CMakeBuildConfiguration *bc) { - QTC_CHECK(m_waitingForParse); + QTC_ASSERT(m_waitingForParse, return); if (!bc || !bc->isActive()) return; @@ -626,18 +745,4 @@ void CMakeProject::createGeneratedCodeModelSupport() CppTools::GeneratedCodeModelSupport::update(m_extraCompilers); } -void CMakeBuildTarget::clear() -{ - executable.clear(); - makeCommand.clear(); - workingDirectory.clear(); - sourceDirectory.clear(); - title.clear(); - targetType = UtilityType; - includeFiles.clear(); - compilerOptions.clear(); - macros.clear(); - files.clear(); -} - } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 40d3382a64..a7eafb30cc 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -26,8 +26,11 @@ #pragma once #include "cmake_global.h" +#include "builddirmanager.h" +#include "cmakebuildtarget.h" #include "cmakeprojectimporter.h" #include "treescanner.h" +#include "builddirmanager.h" #include <projectexplorer/extracompiler.h> #include <projectexplorer/projectmacro.h> @@ -42,40 +45,16 @@ #include <memory> namespace CppTools { class CppProjectUpdater; } +namespace ProjectExplorer { class FileNode; } namespace CMakeProjectManager { namespace Internal { class CMakeBuildConfiguration; class CMakeBuildSettingsWidget; +class CMakeProjectNode; } // namespace Internal -enum TargetType { - ExecutableType = 0, - StaticLibraryType = 2, - DynamicLibraryType = 3, - UtilityType = 64 -}; - -class CMAKE_EXPORT CMakeBuildTarget -{ -public: - QString title; - Utils::FileName executable; // TODO: rename to output? - TargetType targetType = UtilityType; - Utils::FileName workingDirectory; - Utils::FileName sourceDirectory; - Utils::FileName makeCommand; - - // code model - QList<Utils::FileName> includeFiles; - QStringList compilerOptions; - ProjectExplorer::Macros macros; - QList<Utils::FileName> files; - - void clear(); -}; - class CMAKE_EXPORT CMakeProject : public ProjectExplorer::Project { Q_OBJECT @@ -103,6 +82,10 @@ public: ProjectExplorer::ProjectImporter *projectImporter() const final; + bool persistCMakeState(); + void clearCMakeCache(); + bool mustUpdateCMakeStateBeforeBuild(); + protected: RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final; bool setupTarget(ProjectExplorer::Target *t) final; @@ -110,10 +93,10 @@ protected: private: QList<CMakeBuildTarget> buildTargets() const; - enum DataCollectionAction { PARSE = 1, SCAN = 2 }; - void startParsingProject(const DataCollectionAction a); + void handleReparseRequest(int reparseParameters); + + void startParsing(int reparseParameters); - void handleActiveProjectConfigurationChanged(ProjectExplorer::ProjectConfiguration *pc); void handleTreeScanningFinished(); void handleParsingSuccess(Internal::CMakeBuildConfiguration *bc); void handleParsingError(Internal::CMakeBuildConfiguration *bc); @@ -121,19 +104,21 @@ private: void updateProjectData(Internal::CMakeBuildConfiguration *bc); void updateQmlJSCodeModel(); + Internal::CMakeProjectNode * + generateProjectTree(const QList<const ProjectExplorer::FileNode*> &allFiles) const; + void createGeneratedCodeModelSupport(); QStringList filesGeneratedFrom(const QString &sourceFile) const final; void updateTargetRunConfigurations(ProjectExplorer::Target *t); void updateApplicationAndDeploymentTargets(); - bool mustUpdateCMakeStateBeforeBuild(); - // TODO probably need a CMake specific node structure QList<CMakeBuildTarget> m_buildTargets; CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr; QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers; Internal::TreeScanner m_treeScanner; + Internal::BuildDirManager m_buildDirManager; bool m_waitingForScan = false; bool m_waitingForParse = false; @@ -144,6 +129,7 @@ private: mutable std::unique_ptr<Internal::CMakeProjectImporter> m_projectImporter; QTimer m_delayedParsingTimer; + int m_delayedParsingParameters = 0; friend class Internal::CMakeBuildConfiguration; friend class Internal::CMakeBuildSettingsWidget; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index 69416b3ad7..b5291273a1 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -243,7 +243,7 @@ QList<void *> CMakeProjectImporter::examineDirectory(const Utils::FileName &impo } QString errorMessage; - const CMakeConfig config = BuildDirManager::parseConfiguration(cacheFile, &errorMessage); + const CMakeConfig config = BuildDirManager::parseCMakeConfiguration(cacheFile, &errorMessage); if (config.isEmpty() || !errorMessage.isEmpty()) { qCDebug(cmInputLog()) << "Failed to read configuration from" << cacheFile << errorMessage; return { }; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 420e0d0bd2..c4db94a689 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -24,7 +24,6 @@ ****************************************************************************/ #include "cmakeprojectmanager.h" -#include "builddirmanager.h" #include "cmakebuildconfiguration.h" #include "cmakekitinformation.h" #include "cmakeprojectconstants.h" @@ -43,9 +42,6 @@ #include <projectexplorer/session.h> #include <projectexplorer/target.h> -#include <utils/qtcprocess.h> -#include <utils/synchronousprocess.h> - #include <QAction> #include <QDateTime> #include <QIcon> @@ -121,19 +117,15 @@ void CMakeManager::updateCmakeActions() void CMakeManager::clearCMakeCache(Project *project) { - if (!project || !project->activeTarget()) - return; - auto bc = qobject_cast<CMakeBuildConfiguration *>(project->activeTarget()->activeBuildConfiguration()); - if (!bc) + CMakeProject *cmakeProject = qobject_cast<CMakeProject *>(project); + if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration()) return; - bc->clearCache(); + cmakeProject->clearCMakeCache(); } void CMakeManager::runCMake(Project *project) { - if (!project) - return; CMakeProject *cmakeProject = qobject_cast<CMakeProject *>(project); if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration()) return; @@ -146,8 +138,6 @@ void CMakeManager::runCMake(Project *project) void CMakeManager::rescanProject(Project *project) { - if (!project) - return; CMakeProject *cmakeProject = qobject_cast<CMakeProject *>(project); if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration()) return; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro index a8be7ef544..7467e7dbc5 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro @@ -2,9 +2,11 @@ DEFINES += CMAKEPROJECTMANAGER_LIBRARY include(../../qtcreatorplugin.pri) HEADERS = builddirmanager.h \ + builddirparameters.h \ builddirreader.h \ cmakebuildinfo.h \ cmakebuildstep.h \ + cmakebuildtarget.h \ cmakeconfigitem.h \ cmakeproject.h \ cmakeprojectimporter.h \ @@ -36,8 +38,10 @@ HEADERS = builddirmanager.h \ treescanner.h SOURCES = builddirmanager.cpp \ + builddirparameters.cpp \ builddirreader.cpp \ cmakebuildstep.cpp \ + cmakebuildtarget.cpp \ cmakeconfigitem.cpp \ cmakeproject.cpp \ cmakeprojectimporter.cpp \ diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs index fb3c310464..a41890281f 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs @@ -19,6 +19,8 @@ QtcPlugin { ] files: [ + "builddirparameters.cpp", + "builddirparameters.h", "builddirmanager.cpp", "builddirmanager.h", "builddirreader.cpp", @@ -31,6 +33,8 @@ QtcPlugin { "cmakebuildsettingswidget.h", "cmakebuildstep.cpp", "cmakebuildstep.h", + "cmakebuildtarget.cpp", + "cmakebuildtarget.h", "cmakecbpparser.cpp", "cmakecbpparser.h", "cmakeconfigitem.cpp", diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp index 6b821b26b6..4b023aeb0c 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp @@ -166,7 +166,7 @@ QString CMakeRunConfiguration::disabledReason() const auto cp = qobject_cast<CMakeProject *>(target()->project()); QTC_ASSERT(cp, return QString()); - if (cp->hasParsingData() && !cp->hasBuildTarget(m_buildSystemTarget)) + if (!cp->hasBuildTarget(m_buildSystemTarget)) return tr("The project no longer builds the target associated with this run configuration."); return RunConfiguration::disabledReason(); } diff --git a/src/plugins/cmakeprojectmanager/configmodel.cpp b/src/plugins/cmakeprojectmanager/configmodel.cpp index ff43d0cc63..b90f35cff3 100644 --- a/src/plugins/cmakeprojectmanager/configmodel.cpp +++ b/src/plugins/cmakeprojectmanager/configmodel.cpp @@ -200,6 +200,42 @@ QList<ConfigModel::DataItem> ConfigModel::configurationChanges() const }); } +void ConfigModel::setConfiguration(const CMakeConfig &config) +{ + setConfiguration(Utils::transform(config, [](const CMakeConfigItem &i) { + ConfigModel::DataItem j; + j.key = QString::fromUtf8(i.key); + j.value = QString::fromUtf8(i.value); + j.description = QString::fromUtf8(i.documentation); + j.values = i.values; + j.inCMakeCache = i.inCMakeCache; + + j.isAdvanced = i.isAdvanced; + j.isHidden = i.type == CMakeConfigItem::INTERNAL || i.type == CMakeConfigItem::STATIC; + + switch (i.type) { + case CMakeConfigItem::FILEPATH: + j.type = ConfigModel::DataItem::FILE; + break; + case CMakeConfigItem::PATH: + j.type = ConfigModel::DataItem::DIRECTORY; + break; + case CMakeConfigItem::BOOL: + j.type = ConfigModel::DataItem::BOOLEAN; + break; + case CMakeConfigItem::STRING: + j.type = ConfigModel::DataItem::STRING; + break; + default: + j.type = ConfigModel::DataItem::UNKNOWN; + break; + } + + return j; + })); +} + + void ConfigModel::setConfiguration(const QList<ConfigModel::InternalDataItem> &config) { QList<InternalDataItem> tmp = config; diff --git a/src/plugins/cmakeprojectmanager/configmodel.h b/src/plugins/cmakeprojectmanager/configmodel.h index 626d487ac6..6fb96e2990 100644 --- a/src/plugins/cmakeprojectmanager/configmodel.h +++ b/src/plugins/cmakeprojectmanager/configmodel.h @@ -25,6 +25,8 @@ #pragma once +#include "cmakeconfigitem.h" + #include <QAbstractTableModel> #include <utils/treemodel.h> @@ -65,6 +67,7 @@ public: const DataItem::Type type = DataItem::UNKNOWN, const QString &description = QString(), const QStringList &values = QStringList()); + void setConfiguration(const CMakeConfig &config); void setConfiguration(const QList<DataItem> &config); void setKitConfiguration(const QHash<QString, QString> &kitConfig); void flush(); @@ -80,6 +83,7 @@ public: QList<DataItem> configurationChanges() const; + private: class InternalDataItem : public DataItem { @@ -97,9 +101,9 @@ private: QString kitValue; }; - void setConfiguration(const QList<InternalDataItem> &config); void generateTree(); + void setConfiguration(const QList<InternalDataItem> &config); QList<InternalDataItem> m_configuration; QHash<QString, QString> m_kitConfiguration; diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index 7f85e1cae4..74a9f43bd3 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -97,12 +97,15 @@ ServerModeReader::~ServerModeReader() stop(); } -void ServerModeReader::setParameters(const BuildDirReader::Parameters &p) +void ServerModeReader::setParameters(const BuildDirParameters &p) { + QTC_ASSERT(p.cmakeTool, return); + BuildDirReader::setParameters(p); if (!m_cmakeServer) { m_cmakeServer.reset(new ServerMode(p.environment, - p.sourceDirectory, p.buildDirectory, p.cmakeExecutable, + p.sourceDirectory, p.buildDirectory, + p.cmakeTool->cmakeExecutable(), p.generator, p.extraGenerator, p.platform, p.toolset, true, 1)); connect(m_cmakeServer.get(), &ServerMode::errorOccured, @@ -135,14 +138,17 @@ void ServerModeReader::setParameters(const BuildDirReader::Parameters &p) } } -bool ServerModeReader::isCompatible(const BuildDirReader::Parameters &p) +bool ServerModeReader::isCompatible(const BuildDirParameters &p) { + if (!p.cmakeTool) + return false; + // Server mode connection got lost, reset... - if (!m_parameters.cmakeExecutable.isEmpty() && !m_cmakeServer) + if (!m_parameters.cmakeTool->cmakeExecutable().isEmpty() && !m_cmakeServer) return false; - return p.cmakeHasServerMode - && p.cmakeExecutable == m_parameters.cmakeExecutable + return p.cmakeTool->hasServerMode() + && p.cmakeTool->cmakeExecutable() == m_parameters.cmakeTool->cmakeExecutable() && p.environment == m_parameters.environment && p.generator == m_parameters.generator && p.extraGenerator == m_parameters.extraGenerator @@ -154,24 +160,33 @@ bool ServerModeReader::isCompatible(const BuildDirReader::Parameters &p) void ServerModeReader::resetData() { - m_hasData = false; + m_cmakeConfiguration.clear(); + // m_cmakeFiles: Keep these! + m_cmakeInputsFileNodes.clear(); + qDeleteAll(m_projects); // Also deletes targets and filegroups that are its children! + m_projects.clear(); + m_targets.clear(); + m_fileGroups.clear(); } -void ServerModeReader::parse(bool force) +void ServerModeReader::parse(bool forceConfiguration) { emit configurationStarted(); - Core::MessageManager::write(tr("Starting to parse CMake project.")); QTC_ASSERT(m_cmakeServer, return); QVariantMap extra; - if (force || !QDir(m_parameters.buildDirectory.toString()).exists("CMakeCache.txt")) { + if (forceConfiguration || !QDir(m_parameters.buildDirectory.toString()).exists("CMakeCache.txt")) { QStringList cacheArguments = transform(m_parameters.configuration, [this](const CMakeConfigItem &i) { return i.toArgument(m_parameters.expander); }); + Core::MessageManager::write(tr("Starting to parse CMake project, using: \"%1\".") + .arg(cacheArguments.join("\", \""))); cacheArguments.prepend(QString()); // Work around a bug in CMake 3.7.0 and 3.7.1 where // the first argument gets lost! extra.insert("cacheArguments", QVariant(cacheArguments)); + } else { + Core::MessageManager::write(tr("Starting to parse CMake project.")); } m_future.reset(new QFutureInterface<void>()); @@ -205,12 +220,7 @@ bool ServerModeReader::isParsing() const return static_cast<bool>(m_future); } -bool ServerModeReader::hasData() const -{ - return m_hasData; -} - -QList<CMakeBuildTarget> ServerModeReader::buildTargets() const +QList<CMakeBuildTarget> ServerModeReader::takeBuildTargets() { const QList<CMakeBuildTarget> result = transform(m_targets, [](const Target *t) -> CMakeBuildTarget { CMakeBuildTarget ct; @@ -243,8 +253,8 @@ QList<CMakeBuildTarget> ServerModeReader::buildTargets() const CMakeConfig ServerModeReader::takeParsedConfiguration() { - CMakeConfig config = m_cmakeCache; - m_cmakeCache.clear(); + CMakeConfig config = m_cmakeConfiguration; + m_cmakeConfiguration.clear(); return config; } @@ -369,11 +379,6 @@ void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps) : CppTools::ProjectPart::Library); rpps.append(rpp); } - - qDeleteAll(m_projects); // Not used anymore! - m_projects.clear(); - m_targets.clear(); - m_fileGroups.clear(); } void ServerModeReader::handleReply(const QVariantMap &data, const QString &inReplyTo) @@ -412,7 +417,6 @@ void ServerModeReader::handleReply(const QVariantMap &data, const QString &inRep m_future->reportFinished(); m_future.reset(); } - m_hasData = true; Core::MessageManager::write(tr("CMake Project was parsed successfully.")); emit dataAvailable(); } @@ -669,7 +673,7 @@ void ServerModeReader::extractCacheData(const QVariantMap &data) item.values = CMakeConfigItem::cmakeSplitValue(properties.value("STRINGS").toString(), true); config.append(item); } - m_cmakeCache = config; + m_cmakeConfiguration = config; } void ServerModeReader::fixTarget(ServerModeReader::Target *target) const diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h index bf5fe7337e..bfde93ca1c 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.h +++ b/src/plugins/cmakeprojectmanager/servermodereader.h @@ -33,10 +33,11 @@ #include <memory> +namespace ProjectExplorer { class ProjectNode; } + namespace CMakeProjectManager { namespace Internal { - class ServerModeReader : public BuildDirReader { Q_OBJECT @@ -45,18 +46,17 @@ public: ServerModeReader(); ~ServerModeReader() final; - void setParameters(const Parameters &p) final; + void setParameters(const BuildDirParameters &p) final; - bool isCompatible(const Parameters &p) final; + bool isCompatible(const BuildDirParameters &p) final; void resetData() final; - void parse(bool force) final; + void parse(bool forceConfiguration) final; void stop() final; bool isReady() const final; bool isParsing() const final; - bool hasData() const final; - QList<CMakeBuildTarget> buildTargets() const final; + QList<CMakeBuildTarget> takeBuildTargets() final; CMakeConfig takeParsedConfiguration() final; void generateProjectTree(CMakeProjectNode *root, const QList<const ProjectExplorer::FileNode *> &allFiles) final; @@ -160,21 +160,19 @@ private: const QList<ProjectExplorer::FileNode *> knownHeaders, const QList<const ProjectExplorer::FileNode *> &allFiles); - bool m_hasData = false; - std::unique_ptr<ServerMode> m_cmakeServer; std::unique_ptr<QFutureInterface<void>> m_future; int m_progressStepMinimum = 0; int m_progressStepMaximum = 1000; - CMakeConfig m_cmakeCache; + CMakeConfig m_cmakeConfiguration; QSet<Utils::FileName> m_cmakeFiles; QList<ProjectExplorer::FileNode *> m_cmakeInputsFileNodes; QList<Project *> m_projects; - mutable QList<Target *> m_targets; + QList<Target *> m_targets; QList<FileGroup *> m_fileGroups; CMakeParser m_parser; diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp index 2fbe12d28d..99374c0719 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp +++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp @@ -130,7 +130,9 @@ TeaLeafReader::TeaLeafReader() { connect(EditorManager::instance(), &EditorManager::aboutToSave, this, [this](const IDocument *document) { - if (m_cmakeFiles.contains(document->filePath()) || !m_parameters.isAutorun) + if (m_cmakeFiles.contains(document->filePath()) + || !m_parameters.cmakeTool + || !m_parameters.cmakeTool->isAutoRun()) emit dirty(); }); @@ -150,15 +152,15 @@ TeaLeafReader::~TeaLeafReader() resetData(); } -bool TeaLeafReader::isCompatible(const BuildDirReader::Parameters &p) +bool TeaLeafReader::isCompatible(const BuildDirParameters &p) { - return !p.cmakeHasServerMode; + if (!p.cmakeTool) + return false; + return !p.cmakeTool->hasServerMode(); } void TeaLeafReader::resetData() { - m_hasData = false; - qDeleteAll(m_watchedFiles); m_watchedFiles.clear(); @@ -188,11 +190,11 @@ static QString findCbpFile(const QDir &directory) return file; } -void TeaLeafReader::parse(bool force) +void TeaLeafReader::parse(bool forceConfiguration) { const QString cbpFile = findCbpFile(QDir(m_parameters.buildDirectory.toString())); const QFileInfo cbpFileFi = cbpFile.isEmpty() ? QFileInfo() : QFileInfo(cbpFile); - if (!cbpFileFi.exists() || force) { + if (!cbpFileFi.exists() || forceConfiguration) { // Initial create: startCMake(toArguments(m_parameters.configuration, m_parameters.expander)); return; @@ -206,7 +208,6 @@ void TeaLeafReader::parse(bool force) startCMake(QStringList()); } else { extractData(); - m_hasData = true; emit dataAvailable(); } } @@ -228,12 +229,7 @@ bool TeaLeafReader::isParsing() const return m_cmakeProcess && m_cmakeProcess->state() != QProcess::NotRunning; } -bool TeaLeafReader::hasData() const -{ - return m_hasData; -} - -QList<CMakeBuildTarget> TeaLeafReader::buildTargets() const +QList<CMakeBuildTarget> TeaLeafReader::takeBuildTargets() { return m_buildTargets; } @@ -247,7 +243,7 @@ CMakeConfig TeaLeafReader::takeParsedConfiguration() return { }; QString errorMessage; - CMakeConfig result = BuildDirManager::parseConfiguration(cacheFile, &errorMessage); + CMakeConfig result = BuildDirManager::parseCMakeConfiguration(cacheFile, &errorMessage); if (!errorMessage.isEmpty()) { emit errorOccured(errorMessage); @@ -412,6 +408,8 @@ void TeaLeafReader::cleanUpProcess() void TeaLeafReader::extractData() { + QTC_ASSERT(m_parameters.isValid() && m_parameters.cmakeTool, return); + const FileName srcDir = m_parameters.sourceDirectory; const FileName bldDir = m_parameters.buildDirectory; const FileName topCMake = Utils::FileName(srcDir).appendPath("CMakeLists.txt"); @@ -437,7 +435,7 @@ void TeaLeafReader::extractData() // setFolderName CMakeCbpParser cbpparser; // Parsing - if (!cbpparser.parseCbpFile(m_parameters.pathMapper, cbpFile, srcDir)) + if (!cbpparser.parseCbpFile(m_parameters.cmakeTool->pathMapper(), cbpFile, srcDir)) return; m_projectName = cbpparser.projectName(); @@ -460,6 +458,8 @@ void TeaLeafReader::extractData() void TeaLeafReader::startCMake(const QStringList &configurationArguments) { + QTC_ASSERT(m_parameters.isValid() && m_parameters.cmakeTool, return); + const FileName buildDirectory = m_parameters.buildDirectory; QTC_ASSERT(!m_cmakeProcess, return); QTC_ASSERT(!m_parser, return); @@ -503,7 +503,7 @@ void TeaLeafReader::startCMake(const QStringList &configurationArguments) TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); MessageManager::write(tr("Running \"%1 %2\" in %3.") - .arg(m_parameters.cmakeExecutable.toUserOutput()) + .arg(m_parameters.cmakeTool->cmakeExecutable().toUserOutput()) .arg(args) .arg(buildDirectory.toUserOutput())); @@ -513,7 +513,7 @@ void TeaLeafReader::startCMake(const QStringList &configurationArguments) tr("Configuring \"%1\"").arg(m_parameters.projectName), "CMake.Configure"); - m_cmakeProcess->setCommand(m_parameters.cmakeExecutable.toString(), args); + m_cmakeProcess->setCommand(m_parameters.cmakeTool->cmakeExecutable().toString(), args); emit configurationStarted(); m_cmakeProcess->start(); } @@ -549,7 +549,6 @@ void TeaLeafReader::cmakeFinished(int code, QProcess::ExitStatus status) delete m_future; m_future = nullptr; - m_hasData = true; emit dataAvailable(); } @@ -663,7 +662,7 @@ bool TeaLeafReader::extractFlagsFromNinja(const CMakeBuildTarget &buildTarget, // found // Get "all" target's working directory QByteArray ninjaFile; - QString buildNinjaFile = buildTargets().at(0).workingDirectory.toString(); + QString buildNinjaFile = takeBuildTargets().at(0).workingDirectory.toString(); buildNinjaFile += "/build.ninja"; QFile buildNinja(buildNinjaFile); if (buildNinja.exists()) { diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.h b/src/plugins/cmakeprojectmanager/tealeafreader.h index 9853a1b0a2..2e699aecf1 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.h +++ b/src/plugins/cmakeprojectmanager/tealeafreader.h @@ -46,15 +46,14 @@ public: TeaLeafReader(); ~TeaLeafReader() final; - bool isCompatible(const Parameters &p) final; + bool isCompatible(const BuildDirParameters &p) final; void resetData() final; - void parse(bool force) final; + void parse(bool forceConfiguration) final; void stop() final; bool isParsing() const final; - bool hasData() const final; - QList<CMakeBuildTarget> buildTargets() const final; + QList<CMakeBuildTarget> takeBuildTargets() final; CMakeConfig takeParsedConfiguration() final; void generateProjectTree(CMakeProjectNode *root, const QList<const ProjectExplorer::FileNode *> &allFiles) final; @@ -80,8 +79,6 @@ private: ProjectExplorer::IOutputParser *m_parser = nullptr; QFutureInterface<void> *m_future = nullptr; - bool m_hasData = false; - QSet<Utils::FileName> m_cmakeFiles; QString m_projectName; QList<CMakeBuildTarget> m_buildTargets; diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index afbc8da18a..43b6cb212f 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -153,20 +153,20 @@ public: QList<DocumentManager::RecentFile> m_recentFiles; static const int m_maxRecentFiles = 7; - QFileSystemWatcher *m_fileWatcher; // Delayed creation. - QFileSystemWatcher *m_linkWatcher; // Delayed creation (only UNIX/if a link is seen). - bool m_blockActivated; + QFileSystemWatcher *m_fileWatcher = nullptr; // Delayed creation. + QFileSystemWatcher *m_linkWatcher = nullptr; // Delayed creation (only UNIX/if a link is seen). + bool m_blockActivated = false; bool m_checkOnFocusChange = false; - QString m_lastVisitedDirectory; + QString m_lastVisitedDirectory = QDir::currentPath(); QString m_defaultLocationForNewFiles; FileName m_projectsDirectory; - bool m_useProjectsDirectory; + bool m_useProjectsDirectory = true; QString m_buildDirectory; // When we are calling into an IDocument // we don't want to receive a changed() // signal // That makes the code easier - IDocument *m_blockedIDocument; + IDocument *m_blockedIDocument = nullptr; }; static DocumentManager *m_instance; @@ -210,13 +210,7 @@ void DocumentManagerPrivate::onApplicationFocusChange() m_instance->checkForReload(); } -DocumentManagerPrivate::DocumentManagerPrivate() : - m_fileWatcher(0), - m_linkWatcher(0), - m_blockActivated(false), - m_lastVisitedDirectory(QDir::currentPath()), - m_useProjectsDirectory(true), - m_blockedIDocument(0) +DocumentManagerPrivate::DocumentManagerPrivate() { connect(qApp, &QApplication::focusChanged, this, &DocumentManagerPrivate::onApplicationFocusChange); } @@ -261,21 +255,24 @@ static void addFileInfo(IDocument *document, const QString &filePath, const QFileInfo fi(filePath); state.modified = fi.lastModified(); state.permissions = fi.permissions(); - // Add watcher if we don't have that already + // Add state if we don't have already if (!d->m_states.contains(filePathKey)) { FileState state; state.watchedFilePath = filePath; d->m_states.insert(filePathKey, state); - - qCDebug(log) << "adding (" << (isLink ? "link" : "full") << ") watch for" - << state.watchedFilePath; - QFileSystemWatcher *watcher = 0; - if (isLink) - watcher = d->linkWatcher(); - else - watcher = d->fileWatcher(); - watcher->addPath(state.watchedFilePath); } + // Add or update watcher on file path + // This is also used to update the watcher in case of saved (==replaced) files or + // update link targets, even if there are multiple documents registered for it + const QString watchedFilePath = d->m_states.value(filePathKey).watchedFilePath; + qCDebug(log) << "adding (" << (isLink ? "link" : "full") << ") watch for" + << watchedFilePath; + QFileSystemWatcher *watcher = nullptr; + if (isLink) + watcher = d->linkWatcher(); + else + watcher = d->fileWatcher(); + watcher->addPath(watchedFilePath); d->m_states[filePathKey].lastUpdatedState.insert(document, state); } @@ -429,7 +426,7 @@ void DocumentManager::renamedFile(const QString &from, const QString &to) removeFileInfo(document); document->setFilePath(FileName::fromString(to)); addFileInfo(document); - d->m_blockedIDocument = 0; + d->m_blockedIDocument = nullptr; } emit m_instance->allDocumentsRenamed(from, to); } @@ -617,7 +614,7 @@ static bool saveModifiedFilesHelper(const QList<IDocument *> &documents, // There can be several IDocuments pointing to the same file // Prefer one that is not readonly // (even though it *should* not happen that the IDocuments are inconsistent with readonly) - if (!modifiedDocumentsMap.key(name, 0) || !document->isFileReadOnly()) + if (!modifiedDocumentsMap.key(name, nullptr) || !document->isFileReadOnly()) modifiedDocumentsMap.insert(document, name); } } @@ -827,10 +824,17 @@ bool DocumentManager::saveAllModifiedDocumentsSilently(bool *canceled, \a FailedToClose will contain a list of documents that could not be saved if passed into the method. */ -bool DocumentManager::saveModifiedDocumentsSilently(const QList<IDocument *> &documents, bool *canceled, +bool DocumentManager::saveModifiedDocumentsSilently(const QList<IDocument *> &documents, + bool *canceled, QList<IDocument *> *failedToClose) { - return saveModifiedFilesHelper(documents, QString(), canceled, true, QString(), 0, failedToClose); + return saveModifiedFilesHelper(documents, + QString(), + canceled, + true, + QString(), + nullptr, + failedToClose); } /*! @@ -1178,7 +1182,7 @@ void DocumentManager::checkForReload() errorStrings << errorString; } - d->m_blockedIDocument = 0; + d->m_blockedIDocument = nullptr; } if (!filesToDiff.isEmpty()) { diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h index 3cf9b47bfe..0714cdf7bf 100644 --- a/src/plugins/coreplugin/documentmanager.h +++ b/src/plugins/coreplugin/documentmanager.h @@ -80,38 +80,47 @@ public: static QString cleanAbsoluteFilePath(const QString &filePath, ResolveMode resolveMode); static QString filePathKey(const QString &filePath, ResolveMode resolveMode); - static bool saveDocument(IDocument *document, const QString &fileName = QString(), bool *isReadOnly = 0); + static bool saveDocument(IDocument *document, + const QString &fileName = QString(), + bool *isReadOnly = nullptr); static QStringList getOpenFileNames(const QString &filters, const QString &path = QString(), - QString *selectedFilter = 0); - static QString getSaveFileName(const QString &title, const QString &pathIn, - const QString &filter = QString(), QString *selectedFilter = 0); + QString *selectedFilter = nullptr); + static QString getSaveFileName(const QString &title, + const QString &pathIn, + const QString &filter = QString(), + QString *selectedFilter = nullptr); static QString getSaveFileNameWithExtension(const QString &title, const QString &pathIn, const QString &filter); static QString getSaveAsFileName(const IDocument *document); - static bool saveAllModifiedDocumentsSilently(bool *canceled = 0, - QList<IDocument *> *failedToClose = 0); - static bool saveModifiedDocumentsSilently(const QList<IDocument *> &documents, bool *canceled = 0, - QList<IDocument *> *failedToClose = 0); - static bool saveModifiedDocumentSilently(IDocument *document, bool *canceled = 0, - QList<IDocument *> *failedToClose = 0); - - static bool saveAllModifiedDocuments(const QString &message = QString(), bool *canceled = 0, + static bool saveAllModifiedDocumentsSilently(bool *canceled = nullptr, + QList<IDocument *> *failedToClose = nullptr); + static bool saveModifiedDocumentsSilently(const QList<IDocument *> &documents, + bool *canceled = nullptr, + QList<IDocument *> *failedToClose = nullptr); + static bool saveModifiedDocumentSilently(IDocument *document, + bool *canceled = nullptr, + QList<IDocument *> *failedToClose = nullptr); + + static bool saveAllModifiedDocuments(const QString &message = QString(), + bool *canceled = nullptr, const QString &alwaysSaveMessage = QString(), - bool *alwaysSave = 0, - QList<IDocument *> *failedToClose = 0); + bool *alwaysSave = nullptr, + QList<IDocument *> *failedToClose = nullptr); static bool saveModifiedDocuments(const QList<IDocument *> &documents, - const QString &message = QString(), bool *canceled = 0, + const QString &message = QString(), + bool *canceled = nullptr, const QString &alwaysSaveMessage = QString(), - bool *alwaysSave = 0, - QList<IDocument *> *failedToClose = 0); + bool *alwaysSave = nullptr, + QList<IDocument *> *failedToClose = nullptr); static bool saveModifiedDocument(IDocument *document, - const QString &message = QString(), bool *canceled = 0, + const QString &message = QString(), + bool *canceled = nullptr, const QString &alwaysSaveMessage = QString(), - bool *alwaysSave = 0, - QList<IDocument *> *failedToClose = 0); + bool *alwaysSave = nullptr, + QList<IDocument *> *failedToClose = nullptr); static QString fileDialogLastVisitedDirectory(); static void setFileDialogLastVisitedDirectory(const QString &); diff --git a/src/plugins/coreplugin/editormanager/documentmodel.cpp b/src/plugins/coreplugin/editormanager/documentmodel.cpp index 10960e4793..fb6bf68949 100644 --- a/src/plugins/coreplugin/editormanager/documentmodel.cpp +++ b/src/plugins/coreplugin/editormanager/documentmodel.cpp @@ -367,6 +367,7 @@ DocumentModel::Entry *DocumentModelPrivate::removeEditor(IEditor *editor) QTC_ASSERT(d->m_editors.contains(document), return nullptr); d->m_editors[document].removeAll(editor); DocumentModel::Entry *entry = DocumentModel::entryForDocument(document); + QTC_ASSERT(entry, return nullptr); if (d->m_editors.value(document).isEmpty()) { d->m_editors.remove(document); entry->document = new IDocument; diff --git a/src/plugins/coreplugin/locator/basefilefilter.cpp b/src/plugins/coreplugin/locator/basefilefilter.cpp index 86fe5078f8..26db4474cc 100644 --- a/src/plugins/coreplugin/locator/basefilefilter.cpp +++ b/src/plugins/coreplugin/locator/basefilefilter.cpp @@ -26,7 +26,6 @@ #include "basefilefilter.h" #include <coreplugin/editormanager/editormanager.h> -#include <utils/camelhumpmatcher.h> #include <utils/fileutils.h> #include <utils/qtcassert.h> @@ -100,9 +99,8 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil QList<LocatorFilterEntry> goodEntries; const QString entry = QDir::fromNativeSeparators(origEntry); const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry); - const QRegularExpression regexp = containsWildcard(entry) - ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry); + const QRegularExpression regexp = createRegExp(entry); if (!regexp.isValid()) { d->m_current.clear(); // free memory return betterEntries; @@ -143,16 +141,14 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil filterEntry.fileName = path; filterEntry.extraInfo = FileUtils::shortNativePath(FileName(fi)); - LocatorFilterEntry::HighlightInfo::DataType hDataType = LocatorFilterEntry::HighlightInfo::DisplayName; const bool betterMatch = match.capturedStart() == 0; if (hasPathSeparator) { match = regexp.match(filterEntry.extraInfo); - hDataType = LocatorFilterEntry::HighlightInfo::ExtraInfo; + filterEntry.highlightInfo = + highlightInfo(match, LocatorFilterEntry::HighlightInfo::ExtraInfo); + } else { + filterEntry.highlightInfo = highlightInfo(match); } - const CamelHumpMatcher::HighlightingPositions positions = - CamelHumpMatcher::highlightingPositions(match); - filterEntry.highlightInfo = - LocatorFilterEntry::HighlightInfo(positions.starts, positions.lengths, hDataType); if (betterMatch) betterEntries.append(filterEntry); diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index 3a0d897a63..541f7e3166 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -26,6 +26,7 @@ #include "ilocatorfilter.h" #include <coreplugin/coreconstants.h> +#include <utils/camelhumpmatcher.h> #include <QBoxLayout> #include <QCheckBox> @@ -212,7 +213,7 @@ bool ILocatorFilter::containsWildcard(const QString &str) * The regular expression contains capture groups to allow highlighting * matched characters after a match. */ -QRegularExpression ILocatorFilter::createWildcardRegExp(const QString &text) +static QRegularExpression createWildcardRegExp(const QString &text) { QString pattern = '(' + text + ')'; pattern.replace('?', ").("); @@ -221,6 +222,21 @@ QRegularExpression ILocatorFilter::createWildcardRegExp(const QString &text) return QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption); } +QRegularExpression ILocatorFilter::createRegExp(const QString &text) +{ + return containsWildcard(text) ? createWildcardRegExp(text) + : CamelHumpMatcher::createCamelHumpRegExp(text); +} + +LocatorFilterEntry::HighlightInfo ILocatorFilter::highlightInfo( + const QRegularExpressionMatch &match, LocatorFilterEntry::HighlightInfo::DataType dataType) +{ + const CamelHumpMatcher::HighlightingPositions positions = + CamelHumpMatcher::highlightingPositions(match); + + return LocatorFilterEntry::HighlightInfo(positions.starts, positions.lengths, dataType); +} + /*! Specifies a title for configuration dialogs. */ diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.h b/src/plugins/coreplugin/locator/ilocatorfilter.h index e48464f86f..09acb1be20 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.h +++ b/src/plugins/coreplugin/locator/ilocatorfilter.h @@ -144,7 +144,9 @@ public: static Qt::CaseSensitivity caseSensitivity(const QString &str); static bool containsWildcard(const QString &str); - static QRegularExpression createWildcardRegExp(const QString &text); + static QRegularExpression createRegExp(const QString &text); + LocatorFilterEntry::HighlightInfo highlightInfo(const QRegularExpressionMatch &match, + LocatorFilterEntry::HighlightInfo::DataType dataType = LocatorFilterEntry::HighlightInfo::DisplayName); static QString msgConfigureDialogTitle(); static QString msgPrefixLabel(); diff --git a/src/plugins/coreplugin/locator/opendocumentsfilter.cpp b/src/plugins/coreplugin/locator/opendocumentsfilter.cpp index b9b1779529..8a7c6718f8 100644 --- a/src/plugins/coreplugin/locator/opendocumentsfilter.cpp +++ b/src/plugins/coreplugin/locator/opendocumentsfilter.cpp @@ -27,7 +27,6 @@ #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/ieditor.h> -#include <utils/camelhumpmatcher.h> #include <utils/fileutils.h> #include <QAbstractItemModel> @@ -61,9 +60,8 @@ QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locat QList<LocatorFilterEntry> goodEntries; QList<LocatorFilterEntry> betterEntries; const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry); - const QRegularExpression regexp = containsWildcard(entry) - ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry); + const QRegularExpression regexp = createRegExp(entry); if (!regexp.isValid()) return goodEntries; @@ -76,13 +74,10 @@ QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locat QString displayName = editorEntry.displayName; const QRegularExpressionMatch match = regexp.match(displayName); if (match.hasMatch()) { - const CamelHumpMatcher::HighlightingPositions positions = - CamelHumpMatcher::highlightingPositions(match); LocatorFilterEntry filterEntry(this, displayName, QString(fileName + fp.postfix)); filterEntry.extraInfo = FileUtils::shortNativePath(FileName::fromString(fileName)); filterEntry.fileName = fileName; - filterEntry.highlightInfo.starts = positions.starts; - filterEntry.highlightInfo.lengths = positions.lengths; + filterEntry.highlightInfo = highlightInfo(match); if (match.capturedStart() == 0) betterEntries.append(filterEntry); else diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp index 6f528a3f4f..bae78edce6 100644 --- a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp +++ b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp @@ -30,7 +30,6 @@ #include <coreplugin/idocument.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/ieditor.h> -#include <utils/camelhumpmatcher.h> #include <QRegularExpression> @@ -67,9 +66,7 @@ QList<Core::LocatorFilterEntry> CppCurrentDocumentFilter::matchesFor( QList<Core::LocatorFilterEntry> goodEntries; QList<Core::LocatorFilterEntry> betterEntries; - const QRegularExpression regexp = containsWildcard(entry) - ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry); - + const QRegularExpression regexp = createRegExp(entry); if (!regexp.isValid()) return goodEntries; @@ -98,14 +95,13 @@ QList<Core::LocatorFilterEntry> CppCurrentDocumentFilter::matchesFor( Core::LocatorFilterEntry filterEntry(this, name, id, info->icon()); filterEntry.extraInfo = extraInfo; - if (!match.hasMatch()) { + if (match.hasMatch()) { + filterEntry.highlightInfo = highlightInfo(match); + } else { match = regexp.match(extraInfo); - filterEntry.highlightInfo.dataType = Core::LocatorFilterEntry::HighlightInfo::ExtraInfo; + filterEntry.highlightInfo = + highlightInfo(match, Core::LocatorFilterEntry::HighlightInfo::ExtraInfo); } - const CamelHumpMatcher::HighlightingPositions positions = - CamelHumpMatcher::highlightingPositions(match); - filterEntry.highlightInfo.starts = positions.starts; - filterEntry.highlightInfo.lengths = positions.lengths; if (betterMatch) betterEntries.append(filterEntry); diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp index 86028fbe62..977c618855 100644 --- a/src/plugins/cpptools/cpplocatorfilter.cpp +++ b/src/plugins/cpptools/cpplocatorfilter.cpp @@ -28,7 +28,6 @@ #include <coreplugin/editormanager/editormanager.h> #include <utils/algorithm.h> -#include <utils/camelhumpmatcher.h> #include <QRegularExpression> @@ -76,9 +75,8 @@ QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor( const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry); bool hasColonColon = entry.contains(QLatin1String("::")); const IndexItem::ItemType wanted = matchTypes(); - const QRegularExpression regexp = containsWildcard(entry) - ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry); + const QRegularExpression regexp = createRegExp(entry); if (!regexp.isValid()) return goodEntries; @@ -95,10 +93,7 @@ QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor( // to update the match if the displayName is different from matchString if (matchString != filterEntry.displayName) match = regexp.match(filterEntry.displayName); - const CamelHumpMatcher::HighlightingPositions positions = - CamelHumpMatcher::highlightingPositions(match); - filterEntry.highlightInfo.starts = positions.starts; - filterEntry.highlightInfo.lengths = positions.lengths; + filterEntry.highlightInfo = highlightInfo(match); if (matchString.startsWith(entry, caseSensitivityForPrefix)) bestEntries.append(filterEntry); diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index a860e5defa..20c6fcbc69 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -194,22 +194,10 @@ public: CdbEngine::CommandHandler handler; }; -static inline bool validMode(DebuggerStartMode sm) +// Accessed by DebuggerRunTool +DebuggerEngine *createCdbEngine() { - return sm != NoStartMode; -} - -// Accessed by RunControlFactory -DebuggerEngine *createCdbEngine(QStringList *errors, DebuggerStartMode sm) -{ - if (HostOsInfo::isWindowsHost()) { - if (validMode(sm)) - return new CdbEngine(); - errors->append(CdbEngine::tr("Internal error: Invalid start parameters passed for the CDB engine.")); - } else { - errors->append(CdbEngine::tr("Unsupported CDB host system.")); - } - return 0; + return new CdbEngine; } void addCdbOptionPages(QList<Core::IOptionsPage *> *opts) @@ -224,24 +212,27 @@ void addCdbOptionPages(QList<Core::IOptionsPage *> *opts) CdbEngine::CdbEngine() : m_tokenPrefix("<token>"), - m_effectiveStartMode(NoStartMode), - m_accessible(false), - m_specialStopMode(NoSpecialStop), - m_nextCommandToken(0), - m_currentBuiltinResponseToken(-1), - m_extensionCommandPrefix("!" QT_CREATOR_CDB_EXT "."), - m_operateByInstructionPending(true), - m_operateByInstruction(true), // Default CDB setting - m_hasDebuggee(false), - m_wow64State(wow64Uninitialized), - m_elapsedLogTime(0), - m_sourceStepInto(false), - m_watchPointX(0), - m_watchPointY(0), - m_ignoreCdbOutput(false) + m_extensionCommandPrefix("!" QT_CREATOR_CDB_EXT ".") { setObjectName("CdbEngine"); + DisplayFormats stringFormats; + stringFormats.append(SimpleFormat); + stringFormats.append(SeparateFormat); + + WatchHandler *wh = watchHandler(); + wh->addTypeFormats("QString", stringFormats); + wh->addTypeFormats("QString *", stringFormats); + wh->addTypeFormats("QByteArray", stringFormats); + wh->addTypeFormats("QByteArray *", stringFormats); + wh->addTypeFormats("std__basic_string", stringFormats); // Python dumper naming convention for std::[w]string + + DisplayFormats imageFormats; + imageFormats.append(SimpleFormat); + imageFormats.append(EnhancedFormat); + wh->addTypeFormats("QImage", imageFormats); + wh->addTypeFormats("QImage *", imageFormats); + connect(action(OperateByInstruction), &QAction::triggered, this, &CdbEngine::operateByInstructionTriggered); connect(action(CreateFullBacktrace), &QAction::triggered, @@ -477,23 +468,6 @@ void CdbEngine::setupEngine() STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed") notifyEngineSetupFailed(); } - - DisplayFormats stringFormats; - stringFormats.append(SimpleFormat); - stringFormats.append(SeparateFormat); - - WatchHandler *wh = watchHandler(); - wh->addTypeFormats("QString", stringFormats); - wh->addTypeFormats("QString *", stringFormats); - wh->addTypeFormats("QByteArray", stringFormats); - wh->addTypeFormats("QByteArray *", stringFormats); - wh->addTypeFormats("std__basic_string", stringFormats); // Python dumper naming convention for std::[w]string - - DisplayFormats imageFormats; - imageFormats.append(SimpleFormat); - imageFormats.append(EnhancedFormat); - wh->addTypeFormats("QImage", imageFormats); - wh->addTypeFormats("QImage *", imageFormats); } bool CdbEngine::launchCDB(const DebuggerRunParameters &sp, QString *errorMessage) diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 7a80e48dba..0a8b6f5024 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -224,40 +224,40 @@ private: QProcess m_process; QScopedPointer<Utils::ConsoleProcess> m_consoleStub; - DebuggerStartMode m_effectiveStartMode; + DebuggerStartMode m_effectiveStartMode = NoStartMode; QByteArray m_outputBuffer; //! Debugger accessible (expecting commands) - bool m_accessible; - SpecialStopMode m_specialStopMode; + bool m_accessible = false; + SpecialStopMode m_specialStopMode = NoSpecialStop; ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation; - int m_nextCommandToken; + int m_nextCommandToken = 0; QHash<int, DebuggerCommand> m_commandForToken; QString m_currentBuiltinResponse; - int m_currentBuiltinResponseToken; + int m_currentBuiltinResponseToken = -1; QMap<QString, NormalizedSourceFileName> m_normalizedFileCache; const QString m_extensionCommandPrefix; //!< Library name used as prefix - bool m_operateByInstructionPending; //!< Creator operate by instruction action changed. - bool m_operateByInstruction; - bool m_hasDebuggee; + bool m_operateByInstructionPending = true; //!< Creator operate by instruction action changed. + bool m_operateByInstruction = true; // Default CDB setting. + bool m_hasDebuggee = false; enum Wow64State { wow64Uninitialized, noWow64Stack, wow64Stack32Bit, wow64Stack64Bit - } m_wow64State; + } m_wow64State = wow64Uninitialized; QTime m_logTime; - mutable int m_elapsedLogTime; + mutable int m_elapsedLogTime = 0; QString m_extensionMessageBuffer; - bool m_sourceStepInto; - int m_watchPointX; - int m_watchPointY; + bool m_sourceStepInto = false; + int m_watchPointX = 0; + int m_watchPointY = 0; PendingBreakPointMap m_pendingBreakpointMap; PendingBreakPointMap m_insertSubBreakpointMap; PendingBreakPointMap m_pendingSubBreakpointMap; - bool m_autoBreakPointCorrection; + bool m_autoBreakPointCorrection = false; QHash<QString, QString> m_fileNameModuleHash; QMultiHash<QString, quint64> m_symbolAddressCache; - bool m_ignoreCdbOutput; + bool m_ignoreCdbOutput = false; QVariantList m_customSpecialStopData; QList<SourcePathMapping> m_sourcePathMappings; QScopedPointer<GdbMi> m_coreStopReason; diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index 1027c773c1..301135d089 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -191,15 +191,7 @@ enum DebuggerEngineType GdbEngineType = 0x001, CdbEngineType = 0x004, PdbEngineType = 0x008, - QmlEngineType = 0x020, - QmlCppEngineType = 0x040, - LldbEngineType = 0x100, - AllEngineTypes = GdbEngineType - | CdbEngineType - | PdbEngineType - | QmlEngineType - | QmlCppEngineType - | LldbEngineType + LldbEngineType = 0x100 }; enum DebuggerLanguage diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 5178cb631c..6e8d1b63ac 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -128,7 +128,6 @@ public: // Macro-expanded and passed to debugger startup. QString additionalStartupCommands; - DebuggerEngineType masterEngineType = NoEngineType; DebuggerEngineType cppEngineType = NoEngineType; bool isCppDebugging = true; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 6e3e6bdd61..57968096b6 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1179,6 +1179,7 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); auto debugger = new DebuggerRunTool(runControl, kit); + debugger->setInferiorExecutable(executable); if (pid) { debugger->setStartMode(AttachExternal); debugger->setCloseMode(DetachAtClose); @@ -1198,7 +1199,6 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, debugger->setStartMessage(tr("Attaching to core file %1.").arg(coreFile)); } else { debugger->setStartMode(StartExternal); - debugger->setInferiorExecutable(executable); debugger->setRunControlName(tr("Executable file \"%1\"").arg(executable)); debugger->setStartMessage(tr("Debugging file %1.").arg(executable)); } diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 79cf7fc895..97410c7615 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -55,6 +55,8 @@ #include <utils/portlist.h> #include <utils/qtcassert.h> #include <utils/qtcprocess.h> +#include <utils/temporarydirectory.h> +#include <utils/temporaryfile.h> #include <utils/url.h> #include <coreplugin/icore.h> @@ -77,11 +79,11 @@ enum { debug = 0 }; namespace Debugger { namespace Internal { -DebuggerEngine *createCdbEngine(QStringList *error, DebuggerStartMode sm); +DebuggerEngine *createCdbEngine(); DebuggerEngine *createGdbEngine(); DebuggerEngine *createPdbEngine(); -DebuggerEngine *createQmlEngine(bool useTerminal); -DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal); +DebuggerEngine *createQmlEngine(); +DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine); DebuggerEngine *createLldbEngine(); class LocalProcessRunner : public RunWorker @@ -175,10 +177,73 @@ public: Utils::QtcProcess m_proc; }; +class CoreUnpacker : public RunWorker +{ +public: + CoreUnpacker(RunControl *runControl, const QString &coreFileName) + : RunWorker(runControl), m_coreFileName(coreFileName) + {} + + QString coreFileName() const { return m_tempCoreFileName; } + +private: + ~CoreUnpacker() final + { + m_coreUnpackProcess.blockSignals(true); + m_coreUnpackProcess.terminate(); + m_coreUnpackProcess.deleteLater(); + if (m_tempCoreFile.isOpen()) + m_tempCoreFile.close(); + + QFile::remove(m_tempCoreFileName); + } + + void start() final + { + { + Utils::TemporaryFile tmp("tmpcore-XXXXXX"); + tmp.open(); + m_tempCoreFileName = tmp.fileName(); + } + + m_coreUnpackProcess.setWorkingDirectory(TemporaryDirectory::masterDirectoryPath()); + connect(&m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished), + this, &CoreUnpacker::reportStarted); + + const QString msg = DebuggerRunTool::tr("Unpacking core file to %1"); + appendMessage(msg.arg(m_tempCoreFileName), LogMessageFormat); + + if (m_coreFileName.endsWith(".lzo")) { + m_coreUnpackProcess.start("lzop", {"-o", m_tempCoreFileName, "-x", m_coreFileName}); + return; + } + + if (m_coreFileName.endsWith(".gz")) { + appendMessage(msg.arg(m_tempCoreFileName), LogMessageFormat); + m_tempCoreFile.setFileName(m_tempCoreFileName); + m_tempCoreFile.open(QFile::WriteOnly); + connect(&m_coreUnpackProcess, &QProcess::readyRead, this, [this] { + m_tempCoreFile.write(m_coreUnpackProcess.readAll()); + }); + m_coreUnpackProcess.start("gzip", {"-c", "-d", m_coreFileName}); + return; + } + + QTC_CHECK(false); + reportFailure("Unknown file extension in " + m_coreFileName); + } + + QFile m_tempCoreFile; + QString m_coreFileName; + QString m_tempCoreFileName; + QProcess m_coreUnpackProcess; +}; + class DebuggerRunToolPrivate { public: QPointer<TerminalRunner> terminalRunner; + QPointer<CoreUnpacker> coreUnpacker; }; } // namespace Internal @@ -196,7 +261,6 @@ void DebuggerRunTool::setStartMode(DebuggerStartMode startMode) m_runParameters.startMode = AttachToRemoteProcess; m_runParameters.isCppDebugging = false; m_runParameters.isQmlDebugging = true; - m_runParameters.masterEngineType = QmlEngineType; m_runParameters.closeMode = KillAtClose; // FIXME: This is horribly wrong. @@ -376,6 +440,11 @@ void DebuggerRunTool::setStartMessage(const QString &msg) void DebuggerRunTool::setCoreFileName(const QString &coreFile, bool isSnapshot) { + if (coreFile.endsWith(".gz") || coreFile.endsWith(".lzo")) { + d->coreUnpacker = new CoreUnpacker(runControl(), coreFile); + addStartDependency(d->coreUnpacker); + } + m_runParameters.coreFile = coreFile; m_runParameters.isSnapshot = isSnapshot; } @@ -421,29 +490,6 @@ void DebuggerRunTool::addSearchDirectory(const QString &dir) m_runParameters.additionalSearchDirectories.append(dir); } -static QLatin1String engineTypeName(DebuggerEngineType et) -{ - switch (et) { - case Debugger::NoEngineType: - break; - case Debugger::GdbEngineType: - return QLatin1String("Gdb engine"); - case Debugger::CdbEngineType: - return QLatin1String("Cdb engine"); - case Debugger::PdbEngineType: - return QLatin1String("Pdb engine"); - case Debugger::QmlEngineType: - return QLatin1String("QML engine"); - case Debugger::QmlCppEngineType: - return QLatin1String("QML C++ engine"); - case Debugger::LldbEngineType: - return QLatin1String("LLDB command line engine"); - case Debugger::AllEngineTypes: - break; - } - return QLatin1String("No engine"); -} - void DebuggerRunTool::start() { Debugger::Internal::saveModeToRestore(); @@ -469,6 +515,9 @@ void DebuggerRunTool::start() // return; // } + if (d->coreUnpacker) + m_runParameters.coreFile = d->coreUnpacker->coreFileName(); + if (!fixupParameters()) return; @@ -480,47 +529,41 @@ void DebuggerRunTool::start() runControl()->setDisplayName(m_runParameters.displayName); DebuggerEngine *cppEngine = nullptr; + if (!m_engine) { + switch (m_runParameters.cppEngineType) { + case GdbEngineType: + cppEngine = createGdbEngine(); + break; + case CdbEngineType: + if (!HostOsInfo::isWindowsHost()) { + reportFailure(tr("Unsupported CDB host system.")); + return; + } + cppEngine = createCdbEngine(); + break; + case LldbEngineType: + cppEngine = createLldbEngine(); + break; + case PdbEngineType: // FIXME: Yes, Python counts as C++... + cppEngine = createPdbEngine(); + break; + default: + // Can happen for pure Qml. + break; + } - switch (m_runParameters.cppEngineType) { - case GdbEngineType: - cppEngine = createGdbEngine(); - break; - case CdbEngineType: { - QStringList errors; - cppEngine = createCdbEngine(&errors, m_runParameters.startMode); - if (!errors.isEmpty()) { - reportFailure(errors.join('\n')); - return; - } - } - break; - case LldbEngineType: - cppEngine = createLldbEngine(); - break; - case PdbEngineType: // FIXME: Yes, Python counts as C++... - cppEngine = createPdbEngine(); - break; - default: - QTC_CHECK(false); - break; - } - - switch (m_runParameters.masterEngineType) { - case QmlEngineType: - m_engine = createQmlEngine(terminalRunner() != nullptr); - break; - case QmlCppEngineType: + if (m_runParameters.isQmlDebugging) { if (cppEngine) - m_engine = createQmlCppEngine(cppEngine, terminalRunner() != nullptr); - break; - default: + m_engine = createQmlCppEngine(cppEngine); + else + m_engine = createQmlEngine(); + } else { m_engine = cppEngine; - break; + } } if (!m_engine) { - reportFailure(DebuggerPlugin::tr("Unable to create a debugging engine of the type \"%1\""). - arg(engineTypeName(m_runParameters.masterEngineType))); + reportFailure(DebuggerPlugin::tr("Unable to create a debugging engine")); return; } @@ -670,32 +713,25 @@ bool DebuggerRunTool::fixupParameters() } } - if (rp.masterEngineType == NoEngineType) { - if (rp.isQmlDebugging) { - QmlDebug::QmlDebugServicesPreset service; - if (rp.isCppDebugging) { - if (rp.nativeMixedEnabled) { - service = QmlDebug::QmlNativeDebuggerServices; - } else { - rp.masterEngineType = QmlCppEngineType; - service = QmlDebug::QmlDebuggerServices; - } + if (rp.isQmlDebugging) { + QmlDebug::QmlDebugServicesPreset service; + if (rp.isCppDebugging) { + if (rp.nativeMixedEnabled) { + service = QmlDebug::QmlNativeDebuggerServices; } else { - rp.masterEngineType = QmlEngineType; service = QmlDebug::QmlDebuggerServices; } - if (rp.startMode != AttachExternal && rp.startMode != AttachCrashedExternal) { - QString qmlarg = rp.isCppDebugging && rp.nativeMixedEnabled - ? QmlDebug::qmlDebugNativeArguments(service, false) - : QmlDebug::qmlDebugTcpArguments(service, Port(rp.qmlServer.port())); - QtcProcess::addArg(&rp.inferior.commandLineArguments, qmlarg); - } + } else { + service = QmlDebug::QmlDebuggerServices; + } + if (rp.startMode != AttachExternal && rp.startMode != AttachCrashedExternal) { + QString qmlarg = rp.isCppDebugging && rp.nativeMixedEnabled + ? QmlDebug::qmlDebugNativeArguments(service, false) + : QmlDebug::qmlDebugTcpArguments(service, Port(rp.qmlServer.port())); + QtcProcess::addArg(&rp.inferior.commandLineArguments, qmlarg); } } - if (rp.masterEngineType == NoEngineType) - rp.masterEngineType = rp.cppEngineType; - if (rp.startMode == NoStartMode) rp.startMode = StartInternal; @@ -758,7 +794,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit) kit = runConfig->target()->kit(); QTC_ASSERT(kit, return); - m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit); m_runParameters.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); m_runParameters.macroExpander = kit->macroExpander(); m_runParameters.debugger = DebuggerKitInformation::runnable(kit); @@ -778,6 +813,9 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit) m_runParameters.multiProcess = aspect->useMultiProcess(); } + if (m_runParameters.isCppDebugging) + m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit); + const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH"); if (!envBinary.isEmpty()) m_runParameters.debugger.executable = QString::fromLocal8Bit(envBinary); @@ -815,8 +853,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit) m_runParameters.inferior.commandLineArguments.append(' '); m_runParameters.inferior.commandLineArguments.append(args); } - m_runParameters.cppEngineType = PdbEngineType; - m_runParameters.masterEngineType = PdbEngineType; + m_engine = createPdbEngine(); } } } diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index 794ee3ee6b..e6e4f6a181 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -32,9 +32,6 @@ #include <projectexplorer/runconfiguration.h> #include <projectexplorer/devicesupport/deviceusedportsgatherer.h> -#include <ssh/sshconnection.h> // FIXME: Remove after downstream was adapted -#include <QHostAddress> // FIXME: Remove after downstream was adapted - namespace Debugger { namespace Internal { diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h deleted file mode 100644 index da1bca1723..0000000000 --- a/src/plugins/debugger/debuggerstartparameters.h +++ /dev/null @@ -1,2 +0,0 @@ - -// Remove after downstream was adapted diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2370d6f22f..3ae97704ab 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -67,7 +67,6 @@ #include <utils/qtcprocess.h> #include <utils/savedaction.h> #include <utils/synchronousprocess.h> -#include <utils/temporarydirectory.h> #include <utils/temporaryfile.h> #include <QDirIterator> @@ -219,21 +218,6 @@ GdbEngine::GdbEngine() GdbEngine::~GdbEngine() { - if (isCoreEngine()) { - if (m_coreUnpackProcess) { - m_coreUnpackProcess->blockSignals(true); - m_coreUnpackProcess->terminate(); - m_coreUnpackProcess->deleteLater(); - m_coreUnpackProcess = nullptr; - if (m_tempCoreFile.isOpen()) - m_tempCoreFile.close(); - } - if (!m_tempCoreName.isEmpty()) { - QFile tmpFile(m_tempCoreName); - tmpFile.remove(); - } - } - //ExtensionSystem::PluginManager::removeObject(m_debugInfoTaskHandler); delete m_debugInfoTaskHandler; m_debugInfoTaskHandler = 0; @@ -1763,38 +1747,6 @@ void GdbEngine::handleInferiorShutdown(const DebuggerResponse &response) notifyInferiorShutdownFailed(); } -void GdbEngine::notifyAdapterShutdownFailed() -{ - showMessage("ADAPTER SHUTDOWN FAILED"); - CHECK_STATE(EngineShutdownRequested); - notifyEngineShutdownFailed(); -} - -void GdbEngine::notifyAdapterShutdownOk() -{ - CHECK_STATE(EngineShutdownRequested); - showMessage(QString("INITIATE GDBENGINE SHUTDOWN IN STATE %1, PROC: %2") - .arg(lastGoodState()).arg(m_gdbProc.state())); - m_commandsDoneCallback = 0; - switch (m_gdbProc.state()) { - case QProcess::Running: { - if (runParameters().closeMode == KillAndExitMonitorAtClose) - runCommand({"monitor exit"}); - runCommand({"exitGdb", ExitRequest, CB(handleGdbExit)}); - break; - } - case QProcess::NotRunning: - // Cannot find executable. - notifyEngineShutdownOk(); - break; - case QProcess::Starting: - showMessage("GDB NOT REALLY RUNNING; KILLING IT"); - m_gdbProc.kill(); - notifyEngineShutdownFailed(); - break; - } -} - void GdbEngine::handleGdbExit(const DebuggerResponse &response) { if (response.resultClass == ResultExit) { @@ -3767,8 +3719,24 @@ static SourcePathMap mergeStartParametersSourcePathMap(const DebuggerRunParamete // Starting up & shutting down // -void GdbEngine::startGdb(const QStringList &args) +void GdbEngine::setupEngine() { + CHECK_STATE(EngineSetupRequested); + showMessage("TRYING TO START ADAPTER"); + + if (isRemoteEngine() && HostOsInfo::isWindowsHost()) + m_gdbProc.setUseCtrlCStub(runParameters().useCtrlCStub); // This is only set for QNX + + QStringList gdbArgs; + if (isPlainEngine()) { + if (!m_outputCollector.listen()) { + handleAdapterStartFailed(tr("Cannot set up communication with child process: %1") + .arg(m_outputCollector.errorString())); + return; + } + gdbArgs.append("--tty=" + m_outputCollector.serverName()); + } + const QString tests = QString::fromLocal8Bit(qgetenv("QTC_DEBUGGER_TESTS")); foreach (const QStringRef &test, tests.splitRef(QLatin1Char(','))) m_testCases.insert(test.toInt()); @@ -3787,12 +3755,10 @@ void GdbEngine::startGdb(const QStringList &args) return; } - QStringList gdbArgs; gdbArgs << "-i"; gdbArgs << "mi"; if (!boolSetting(LoadGdbInit)) gdbArgs << "-n"; - gdbArgs += args; connect(&m_gdbProc, &QProcess::errorOccurred, this, &GdbEngine::handleGdbError); connect(&m_gdbProc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), @@ -4162,27 +4128,6 @@ void GdbEngine::notifyInferiorSetupFailedHelper(const QString &msg) notifyInferiorSetupFailed(); } -void GdbEngine::handleAdapterCrashed(const QString &msg) -{ - showMessage("ADAPTER CRASHED"); - - // The adapter is expected to have cleaned up after itself when we get here, - // so the effect is about the same as AdapterStartFailed => use it. - // Don't bother with state transitions - this can happen in any state and - // the end result is always the same, so it makes little sense to find a - // "path" which does not assert. - if (state() == EngineSetupRequested) - notifyEngineSetupFailed(); - else - notifyEngineIll(); - - // No point in being friendly here ... - m_gdbProc.kill(); - - if (!msg.isEmpty()) - AsynchronousMessageBox::critical(tr("Adapter crashed"), msg); -} - void GdbEngine::createFullBacktrace() { DebuggerCommand cmd("thread apply all bt full", NeedsTemporaryStop | ConsoleCommand); @@ -4314,61 +4259,12 @@ bool GdbEngine::isTermEngine() const return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && terminal(); } -void GdbEngine::setupEngine() -{ - m_startMode = runParameters().startMode; - - CHECK_STATE(EngineSetupRequested); - showMessage("TRYING TO START ADAPTER"); - - if (isAttachEngine()) { - - startGdb(); - - } else if (isRemoteEngine()) { - - if (HostOsInfo::isWindowsHost()) - m_gdbProc.setUseCtrlCStub(runParameters().useCtrlCStub); // This is only set for QNX - - startGdb(); - - } else if (isTermEngine()) { - - showMessage("TRYING TO START ADAPTER"); - - startGdb(); - - } else if (isCoreEngine()) { - - CHECK_STATE(EngineSetupRequested); - showMessage("TRYING TO START ADAPTER"); - - const DebuggerRunParameters &rp = runParameters(); - m_executable = rp.inferior.executable; - QFileInfo fi(rp.coreFile); - m_coreName = fi.absoluteFilePath(); - - unpackCoreIfNeeded(); - - } else if (isPlainEngine()) { - - QStringList gdbArgs; - - if (!m_outputCollector.listen()) { - handleAdapterStartFailed(tr("Cannot set up communication with child process: %1") - .arg(m_outputCollector.errorString())); - return; - } - gdbArgs.append("--tty=" + m_outputCollector.serverName()); - - startGdb(gdbArgs); - } -} - void GdbEngine::setupInferior() { CHECK_STATE(InferiorSetupRequested); + const DebuggerRunParameters &rp = runParameters(); + if (isAttachEngine()) { // Task 254674 does not want to remove them //qq->breakHandler()->removeAllBreakpoints(); @@ -4377,7 +4273,6 @@ void GdbEngine::setupInferior() } else if (isRemoteEngine()) { setLinuxOsAbi(); - const DebuggerRunParameters &rp = runParameters(); QString symbolFile; if (!rp.symbolFile.isEmpty()) { QFileInfo fi(rp.symbolFile); @@ -4438,8 +4333,30 @@ void GdbEngine::setupInferior() } else if (isCoreEngine()) { setLinuxOsAbi(); + + QString executable = rp.inferior.executable; + + if (executable.isEmpty()) { + CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(rp.debugger, rp.coreFile); + + if (!cinfo.isCore) { + AsynchronousMessageBox::warning(tr("Error Loading Core File"), + tr("The specified file does not appear to be a core file.")); + notifyInferiorSetupFailed(); + return; + } + + executable = cinfo.foundExecutableName; + if (executable.isEmpty()) { + AsynchronousMessageBox::warning(tr("Error Loading Symbols"), + tr("No executable to load symbols from specified core.")); + notifyInferiorSetupFailed(); + return; + } + } + // Do that first, otherwise no symbols are loaded. - QFileInfo fi(m_executable); + QFileInfo fi(executable); QString path = fi.absoluteFilePath(); runCommand({"-file-exec-and-symbols \"" + path + '"', CB(handleFileExecAndSymbols)}); @@ -4501,7 +4418,7 @@ void GdbEngine::runEngine() } else if (isCoreEngine()) { - runCommand({"target core " + coreFileName(), CB(handleTargetCore)}); + runCommand({"target core " + runParameters().coreFile, CB(handleTargetCore)}); } else if (isTermEngine()) { @@ -4628,7 +4545,27 @@ void GdbEngine::shutdownEngine() m_outputCollector.shutdown(); } - notifyAdapterShutdownOk(); + CHECK_STATE(EngineShutdownRequested); + showMessage(QString("INITIATE GDBENGINE SHUTDOWN IN STATE %1, PROC: %2") + .arg(lastGoodState()).arg(m_gdbProc.state())); + m_commandsDoneCallback = 0; + switch (m_gdbProc.state()) { + case QProcess::Running: { + if (runParameters().closeMode == KillAndExitMonitorAtClose) + runCommand({"monitor exit"}); + runCommand({"exitGdb", ExitRequest, CB(handleGdbExit)}); + break; + } + case QProcess::NotRunning: + // Cannot find executable. + notifyEngineShutdownOk(); + break; + case QProcess::Starting: + showMessage("GDB NOT REALLY RUNNING; KILLING IT"); + m_gdbProc.kill(); + notifyEngineShutdownFailed(); + break; + } } void GdbEngine::handleFileExecAndSymbols(const DebuggerResponse &response) @@ -4652,7 +4589,7 @@ void GdbEngine::handleFileExecAndSymbols(const DebuggerResponse &response) } else if (isCoreEngine()) { - QString core = coreFileName(); + QString core = runParameters().coreFile; if (response.resultClass == ResultDone) { showMessage(tr("Symbols found."), StatusBar); handleInferiorPrepared(); @@ -4954,7 +4891,11 @@ CoreInfo CoreInfo::readExecutableNameFromCore(const StandardRunnable &debugger, cinfo.rawStringFromCore = QString::fromLocal8Bit(reader.readCoreName(&cinfo.isCore)); cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile); #else - QStringList args = {"-nx", "-batch", "-c", coreFile}; + QStringList args = {"-nx", "-batch"}; + // Multiarch GDB on Windows crashes if osabi is cygwin (the default) when opening a core dump. + if (HostOsInfo::isWindowsHost()) + args += {"-ex", "set osabi GNU/Linux"}; + args += {"-ex", "core " + coreFile}; SynchronousProcess proc; QStringList envLang = QProcess::systemEnvironment(); @@ -4981,41 +4922,6 @@ CoreInfo CoreInfo::readExecutableNameFromCore(const StandardRunnable &debugger, return cinfo; } -void GdbEngine::continueSetupEngine() -{ - if (isCoreEngine()) { - bool isCore = true; - if (m_coreUnpackProcess) { - isCore = m_coreUnpackProcess->exitCode() == 0; - m_coreUnpackProcess->deleteLater(); - m_coreUnpackProcess = 0; - if (m_tempCoreFile.isOpen()) - m_tempCoreFile.close(); - } - if (isCore && m_executable.isEmpty()) { - CoreInfo cinfo = - CoreInfo::readExecutableNameFromCore(runParameters().debugger, coreFileName()); - - if (cinfo.isCore) { - m_executable = cinfo.foundExecutableName; - if (m_executable.isEmpty()) { - AsynchronousMessageBox::warning(tr("Error Loading Symbols"), - tr("No executable to load symbols from specified core.")); - notifyEngineSetupFailed(); - return; - } - } - } - if (isCore) { - startGdb(); - } else { - AsynchronousMessageBox::warning(tr("Error Loading Core File"), - tr("The specified file does not appear to be a core file.")); - notifyEngineSetupFailed(); - } - } -} - void GdbEngine::handleTargetCore(const DebuggerResponse &response) { CHECK_STATE(EngineRunRequested); @@ -5045,50 +4951,6 @@ void GdbEngine::handleCoreRoundTrip(const DebuggerResponse &response) QTimer::singleShot(1000, this, &GdbEngine::loadAllSymbols); } -static QString tempCoreFilename() -{ - Utils::TemporaryFile tmp("tmpcore-XXXXXX"); - tmp.open(); - return tmp.fileName(); -} - -void GdbEngine::unpackCoreIfNeeded() -{ - QStringList arguments; - const QString msg = "Unpacking core file to %1"; - if (m_coreName.endsWith(".lzo")) { - m_tempCoreName = tempCoreFilename(); - showMessage(msg.arg(m_tempCoreName)); - arguments << "-o" << m_tempCoreName << "-x" << m_coreName; - m_coreUnpackProcess = new QProcess(this); - m_coreUnpackProcess->setWorkingDirectory(TemporaryDirectory::masterDirectoryPath()); - m_coreUnpackProcess->start("lzop", arguments); - connect(m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished), - this, &GdbEngine::continueSetupEngine); - } else if (m_coreName.endsWith(".gz")) { - m_tempCoreName = tempCoreFilename(); - showMessage(msg.arg(m_tempCoreName)); - m_tempCoreFile.setFileName(m_tempCoreName); - m_tempCoreFile.open(QFile::WriteOnly); - arguments << "-c" << "-d" << m_coreName; - m_coreUnpackProcess = new QProcess(this); - m_coreUnpackProcess->setWorkingDirectory(TemporaryDirectory::masterDirectoryPath()); - m_coreUnpackProcess->start("gzip", arguments); - connect(m_coreUnpackProcess, &QProcess::readyRead, this, [this] { - m_tempCoreFile.write(m_coreUnpackProcess->readAll()); - }); - connect(m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished), - this, &GdbEngine::continueSetupEngine); - } else { - continueSetupEngine(); - } -} - -QString GdbEngine::coreFileName() const -{ - return m_tempCoreName.isEmpty() ? m_coreName : m_tempCoreName; -} - void GdbEngine::doUpdateLocals(const UpdateParameters ¶ms) { m_pendingBreakpointRequests = 0; diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 506f68c34c..5d481f590f 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -96,7 +96,6 @@ private: ////////// General Interface ////////// ////////// Gdb Process Management ////////// - void startGdb(const QStringList &args = QStringList()); void handleInferiorShutdown(const DebuggerResponse &response); void handleGdbExit(const DebuggerResponse &response); void setLinuxOsAbi(); @@ -120,13 +119,6 @@ private: ////////// General Interface ////////// // The engine is still running just fine, but it failed to acquire a debuggee. void notifyInferiorSetupFailedHelper(const QString &msg); - void notifyAdapterShutdownOk(); - void notifyAdapterShutdownFailed(); - - // Something went wrong with the adapter *after* adapterStarted() was emitted. - // Make sure to clean up everything before emitting this signal. - void handleAdapterCrashed(const QString &msg); - void handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus); void handleGdbError(QProcess::ProcessError error); void readGdbStandardOutput(); @@ -445,19 +437,10 @@ private: ////////// General Interface ////////// // Core void handleTargetCore(const DebuggerResponse &response); void handleCoreRoundTrip(const DebuggerResponse &response); - void unpackCoreIfNeeded(); QString coreFileName() const; - QString coreName() const; - void continueSetupEngine(); QString mainFunction() const; - QString m_executable; - QString m_coreName; - QString m_tempCoreName; - QProcess *m_coreUnpackProcess = nullptr; - QFile m_tempCoreFile; - Utils::QtcProcess m_gdbProc; OutputCollector m_outputCollector; QString m_errorString; diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index a5a9810b9b..77e5204dc9 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -48,9 +48,9 @@ enum { debug = 0 }; #define CHECK_STATE(s) do { checkState(s, __FILE__, __LINE__); } while (0) -DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal) +DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine) { - return new QmlCppEngine(cppEngine, useTerminal); + return new QmlCppEngine(cppEngine); } @@ -60,10 +60,10 @@ DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal) // //////////////////////////////////////////////////////////////////////// -QmlCppEngine::QmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal) +QmlCppEngine::QmlCppEngine(DebuggerEngine *cppEngine) { setObjectName("QmlCppEngine"); - m_qmlEngine = new QmlEngine(useTerminal); + m_qmlEngine = new QmlEngine; m_qmlEngine->setMasterEngine(this); m_cppEngine = cppEngine; m_cppEngine->setMasterEngine(this); diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index 9dcfb3284a..1a6bffb7c5 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -37,7 +37,7 @@ class QmlCppEngine : public DebuggerEngine Q_OBJECT public: - QmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal); + explicit QmlCppEngine(DebuggerEngine *cppEngine); ~QmlCppEngine() override; bool canDisplayTooltip() const override; diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index bfdf956b72..0783dc258d 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -246,7 +246,7 @@ static void updateDocument(IDocument *document, const QTextDocument *textDocumen // /////////////////////////////////////////////////////////////////////// -QmlEngine::QmlEngine(bool useTerminal) +QmlEngine::QmlEngine() : d(new QmlEnginePrivate(this, new QmlDebugConnection(this))) { setObjectName("QmlEngine"); @@ -266,12 +266,6 @@ QmlEngine::QmlEngine(bool useTerminal) connect(&d->applicationLauncher, &ApplicationLauncher::processStarted, this, &QmlEngine::handleLauncherStarted); - // we won't get any debug output - if (useTerminal) { - d->retryOnConnectFail = true; - d->automaticConnect = true; - } - debuggerConsole()->setScriptEvaluator([this](const QString &expr) { executeDebuggerCommand(expr, QmlLanguage); }); @@ -522,6 +516,12 @@ void QmlEngine::closeConnection() void QmlEngine::runEngine() { + // we won't get any debug output + if (!terminal()) { + d->retryOnConnectFail = true; + d->automaticConnect = true; + } + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); if (!isSlaveEngine()) { @@ -2481,9 +2481,9 @@ void QmlEnginePrivate::flushSendBuffer() sendBuffer.clear(); } -DebuggerEngine *createQmlEngine(bool useTerminal) +DebuggerEngine *createQmlEngine() { - return new QmlEngine(useTerminal); + return new QmlEngine; } } // Internal diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 9e95d0041c..36d89800a7 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -43,7 +43,7 @@ class QmlEngine : public DebuggerEngine Q_OBJECT public: - explicit QmlEngine(bool useTerminal); + QmlEngine(); ~QmlEngine() override; void logServiceStateChange(const QString &service, float version, diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 8deea9816d..f2cdc4750d 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -2863,8 +2863,7 @@ bool GitClient::canRebase(const QString &workingDirectory) const void GitClient::rebase(const QString &workingDirectory, const QString &argument) { - VcsCommand *command = vcsExecAbortable(workingDirectory, {"rebase", argument}); - GitProgressParser::attachToCommand(command); + vcsExecAbortable(workingDirectory, {"rebase", argument}, true); } void GitClient::cherryPick(const QString &workingDirectory, const QString &argument) @@ -2880,7 +2879,8 @@ void GitClient::revert(const QString &workingDirectory, const QString &argument) // Executes a command asynchronously. Work tree is expected to be clean. // Stashing is handled prior to this call. VcsCommand *GitClient::vcsExecAbortable(const QString &workingDirectory, - const QStringList &arguments) + const QStringList &arguments, + bool createProgressParser) { QTC_ASSERT(!arguments.isEmpty(), return nullptr); @@ -2890,8 +2890,10 @@ VcsCommand *GitClient::vcsExecAbortable(const QString &workingDirectory, command->setCookie(workingDirectory); command->addFlags(VcsCommand::ShowSuccessMessage); command->addJob(vcsBinary(), arguments, 0); - command->execute(); ConflictHandler::attachToCommand(command, abortCommand); + if (createProgressParser) + GitProgressParser::attachToCommand(command); + command->execute(); return command; } @@ -2929,8 +2931,7 @@ void GitClient::interactiveRebase(const QString &workingDirectory, const QString arguments << commit + '^'; if (fixup) m_disableEditor = true; - VcsCommand *command = vcsExecAbortable(workingDirectory, arguments); - GitProgressParser::attachToCommand(command); + vcsExecAbortable(workingDirectory, arguments, true); if (fixup) m_disableEditor = false; } diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 92988be65d..7d26709c40 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -124,7 +124,9 @@ public: Utils::FileName vcsBinary() const override; unsigned gitVersion(QString *errorMessage = nullptr) const; - VcsBase::VcsCommand *vcsExecAbortable(const QString &workingDirectory, const QStringList &arguments); + VcsBase::VcsCommand *vcsExecAbortable(const QString &workingDirectory, + const QStringList &arguments, + bool createProgressParser = false); QString findRepositoryForDirectory(const QString &dir) const; QString findGitDirForRepository(const QString &repositoryDir) const; diff --git a/src/plugins/projectexplorer/dependenciespanel.cpp b/src/plugins/projectexplorer/dependenciespanel.cpp index fed8a6a653..595b5ca5a7 100644 --- a/src/plugins/projectexplorer/dependenciespanel.cpp +++ b/src/plugins/projectexplorer/dependenciespanel.cpp @@ -29,7 +29,9 @@ #include <coreplugin/fileiconprovider.h> #include <coreplugin/icore.h> + #include <utils/detailswidget.h> +#include <utils/algorithm.h> #include <QDebug> #include <QSize> @@ -47,10 +49,8 @@ namespace Internal { DependenciesModel::DependenciesModel(Project *project, QObject *parent) : QAbstractListModel(parent) , m_project(project) - , m_projects(SessionManager::projects()) { - // We can't select ourselves as a dependency - m_projects.removeAll(m_project); + resetModel(); SessionManager *sessionManager = SessionManager::instance(); connect(sessionManager, &SessionManager::projectRemoved, @@ -59,7 +59,6 @@ DependenciesModel::DependenciesModel(Project *project, QObject *parent) this, &DependenciesModel::resetModel); connect(sessionManager, &SessionManager::sessionLoaded, this, &DependenciesModel::resetModel); -// qDebug()<<"Dependencies Model"<<this<<"for project"<<project<<"("<<project->file()->fileName()<<")"; } void DependenciesModel::resetModel() @@ -67,6 +66,9 @@ void DependenciesModel::resetModel() beginResetModel(); m_projects = SessionManager::projects(); m_projects.removeAll(m_project); + Utils::sort(m_projects, [](Project *a, Project *b) { + return a->displayName() < b->displayName(); + }); endResetModel(); } diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index 9d29ead1a1..f981545c69 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -441,6 +441,8 @@ void FolderNavigationWidgetFactory::insertRootDirectory(const RootDirectory &dir const int index = rootIndex(directory.id); if (index < 0) m_rootDirectories.append(directory); + else + m_rootDirectories[index] = directory; emit m_instance->rootDirectoryAdded(directory); } diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index ad02ca2ef6..884798ecf5 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -431,14 +431,32 @@ bool GccToolChain::isValid() const static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath, const Environment &env) { - const Utils::FileName path = env.searchInPath(compilerPath.fileName(), Utils::FileNameList(), - [](const FileName &pathEntry) { - return !pathEntry.toString().contains("icecc") - && !pathEntry.toString().contains("distcc"); + // Find the "real" compiler if icecc, distcc or similar are in use. Ignore ccache, since that + // is local already. + + // Get the path to the compiler, ignoring direct calls to icecc and distcc as we can not + // do anything about those. + const Utils::FileName compilerDir = compilerPath.parentDir(); + const QString compilerDirString = compilerDir.toString(); + if (!compilerDirString.contains("icecc") && !compilerDirString.contains("distcc")) + return compilerPath; + + FileNameList pathComponents = env.path(); + auto it = std::find_if(pathComponents.begin(), pathComponents.end(), + [compilerDir](const FileName &p) { + return p == compilerDir; }); + if (it != pathComponents.end()) { + std::rotate(pathComponents.begin(), it, pathComponents.end()); + pathComponents.removeFirst(); // remove directory of compilerPath + // No need to put it at the end again, it is in PATH anyway... + } + + // This effectively searches the PATH twice, once via pathComponents and once via PATH itself: + // searchInPath filters duplicates, so that will not hurt. + const Utils::FileName path = env.searchInPath(compilerPath.fileName(), pathComponents); - QTC_ASSERT(!path.isEmpty(), return compilerPath); - return path; + return path.isEmpty() ? compilerPath : path; } ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() const diff --git a/src/plugins/projectexplorer/images/devicestatusindicator.png b/src/plugins/projectexplorer/images/devicestatusindicator.png Binary files differindex 44e045cfb4..b8bd37e7f8 100644 --- a/src/plugins/projectexplorer/images/devicestatusindicator.png +++ b/src/plugins/projectexplorer/images/devicestatusindicator.png diff --git a/src/plugins/projectexplorer/images/devicestatusindicator@2x.png b/src/plugins/projectexplorer/images/devicestatusindicator@2x.png Binary files differindex 7f03474cd0..804047b211 100644 --- a/src/plugins/projectexplorer/images/devicestatusindicator@2x.png +++ b/src/plugins/projectexplorer/images/devicestatusindicator@2x.png diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index 34578f64b8..71d3dba0ea 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -74,16 +74,19 @@ QList<Task> SysRootKitInformation::validate(const Kit *k) const if (dir.isEmpty()) return result; + if (dir.toString().startsWith("target:") || dir.toString().startsWith("remote:")) + return result; + const QFileInfo fi = dir.toFileInfo(); if (!fi.exists()) { - result << Task(Task::Error, tr("Sys Root \"%1\" does not exist in the file system.").arg(dir.toUserOutput()), + result << Task(Task::Warning, tr("Sys Root \"%1\" does not exist in the file system.").arg(dir.toUserOutput()), Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)); } else if (!fi.isDir()) { - result << Task(Task::Error, tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput()), + result << Task(Task::Warning, tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput()), Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)); } else if (QDir(dir.toString()).entryList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) { - result << Task(Task::Error, tr("Sys Root \"%1\" is empty.").arg(dir.toUserOutput()), + result << Task(Task::Warning, tr("Sys Root \"%1\" is empty.").arg(dir.toUserOutput()), Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)); } return result; diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.cpp b/src/plugins/projectexplorer/miniprojecttargetselector.cpp index 499ef3da69..f41b9f73a4 100644 --- a/src/plugins/projectexplorer/miniprojecttargetselector.cpp +++ b/src/plugins/projectexplorer/miniprojecttargetselector.cpp @@ -1102,7 +1102,7 @@ bool MiniProjectTargetSelector::addedBuildConfiguration(BuildConfiguration *bc) bool MiniProjectTargetSelector::removedBuildConfiguration(BuildConfiguration *bc) { - if (bc->target() == m_project->activeTarget()) + if (bc->target() != m_project->activeTarget()) return false; m_listWidgets[BUILD]->removeProjectConfiguration(bc); @@ -1120,7 +1120,7 @@ bool MiniProjectTargetSelector::addedDeployConfiguration(DeployConfiguration *dc bool MiniProjectTargetSelector::removedDeployConfiguration(DeployConfiguration *dc) { - if (dc->target() != m_project->activeTarget()) + if (!m_project || dc->target() != m_project->activeTarget()) return false; m_listWidgets[DEPLOY]->removeProjectConfiguration(dc); @@ -1128,7 +1128,7 @@ bool MiniProjectTargetSelector::removedDeployConfiguration(DeployConfiguration * } bool MiniProjectTargetSelector::addedRunConfiguration(RunConfiguration *rc) { - if (rc->target() != m_project->activeTarget()) + if (!m_project || rc->target() != m_project->activeTarget()) return false; m_listWidgets[RUN]->addProjectConfiguration(rc); @@ -1137,7 +1137,7 @@ bool MiniProjectTargetSelector::addedRunConfiguration(RunConfiguration *rc) bool MiniProjectTargetSelector::removedRunConfiguration(RunConfiguration *rc) { - if (rc->target() != m_project->activeTarget()) + if (!m_project || rc->target() != m_project->activeTarget()) return false; m_listWidgets[RUN]->removeProjectConfiguration(rc); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 5cb8ac5850..6ec591b6ab 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2625,8 +2625,16 @@ void ProjectExplorerPluginPrivate::projectAdded(Project *pro) m_projectsMode->setEnabled(true); // more specific action en and disabling ? pro->subscribeSignal(&BuildConfiguration::enabledChanged, this, [this]() { - if (static_cast<BuildConfiguration *>(sender())->isActive()) + auto bc = qobject_cast<BuildConfiguration *>(sender()); + if (bc && bc->isActive() && bc->project() == SessionManager::startupProject()) { updateActions(); + emit m_instance->updateRunActions(); + } + }); + pro->subscribeSignal(&RunConfiguration::requestRunActionsUpdate, this, [this]() { + auto rc = qobject_cast<RunConfiguration *>(sender()); + if (rc && rc->isActive() && rc->project() == SessionManager::startupProject()) + emit m_instance->updateRunActions(); }); } @@ -2704,15 +2712,6 @@ void ProjectExplorerPluginPrivate::activeRunConfigurationChanged() rc = startupProject->activeTarget()->activeRunConfiguration(); if (rc == previousRunConfiguration) return; - if (previousRunConfiguration) { - disconnect(previousRunConfiguration.data(), &RunConfiguration::requestRunActionsUpdate, - m_instance, &ProjectExplorerPlugin::updateRunActions); - } - previousRunConfiguration = rc; - if (rc) { - connect(rc, &RunConfiguration::requestRunActionsUpdate, - m_instance, &ProjectExplorerPlugin::updateRunActions); - } emit m_instance->updateRunActions(); } @@ -2725,15 +2724,7 @@ void ProjectExplorerPluginPrivate::activeBuildConfigurationChanged() bc = startupProject->activeTarget()->activeBuildConfiguration(); if (bc == previousBuildConfiguration) return; - if (previousBuildConfiguration) { - disconnect(previousBuildConfiguration.data(), &BuildConfiguration::enabledChanged, - m_instance, &ProjectExplorerPlugin::updateRunActions); - } - previousBuildConfiguration = bc; - if (bc) { - connect(bc, &BuildConfiguration::enabledChanged, - m_instance, &ProjectExplorerPlugin::updateRunActions); - } + updateActions(); emit m_instance->updateRunActions(); } diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index f96414e781..b103bdf132 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -364,7 +364,7 @@ void SessionManager::setActiveDeployConfiguration(Target *target, DeployConfigur void SessionManager::setStartupProject(Project *startupProject) { - QTC_ASSERT(!startupProject + QTC_ASSERT((!startupProject && d->m_projects.isEmpty()) || (startupProject && d->m_projects.contains(startupProject)), return); if (d->m_startupProject == startupProject) @@ -498,7 +498,6 @@ bool SessionManager::save() */ void SessionManager::closeAllProjects() { - setStartupProject(nullptr); removeProjects(projects()); } @@ -714,11 +713,11 @@ void SessionManager::configureEditors(Project *project) } } -void SessionManager::removeProjects(QList<Project *> remove) +void SessionManager::removeProjects(const QList<Project *> &remove) { QMap<QString, QStringList> resMap; - foreach (Project *pro, remove) + for (Project *pro : remove) emit m_instance->aboutToRemoveProject(pro); // Refresh dependencies @@ -741,31 +740,29 @@ void SessionManager::removeProjects(QList<Project *> remove) } d->m_depMap = resMap; - - // TODO: Clear m_modelProjectHash + bool changeStartupProject = false; // Delete projects - foreach (Project *pro, remove) { + for (Project *pro : remove) { pro->saveSettings(); // Remove the project node: d->m_projects.removeOne(pro); if (pro == d->m_startupProject) - setStartupProject(nullptr); + changeStartupProject = true; disconnect(pro, &Project::fileListChanged, m_instance, &SessionManager::clearProjectFileCache); d->m_projectFileCache.remove(pro); emit m_instance->projectRemoved(pro); FolderNavigationWidgetFactory::removeRootDirectory(projectFolderId(pro)); - delete pro; } - if (!startupProject()) { - if (hasProjects()) - setStartupProject(projects().first()); - } + if (changeStartupProject) + setStartupProject(hasProjects() ? projects().first() : nullptr); + + qDeleteAll(remove); } /*! @@ -1017,23 +1014,10 @@ bool SessionManager::loadSession(const QString &session) return false; } - setStartupProject(nullptr); - - QList<Project *> oldProjects = projects(); - auto it = oldProjects.begin(); - auto end = oldProjects.end(); - - while (it != end) { - int index = fileList.indexOf((*it)->projectFilePath().toString()); - if (index != -1) { - fileList.removeAt(index); - it = oldProjects.erase(it); - } else { - ++it; - } - } - - removeProjects(oldProjects); + // find a list of projects to close later + const QList<Project *> oldProjects = Utils::filtered(projects(), [&fileList](Project *p) { + return !fileList.contains(p->projectFilePath().toString()); + }); d->m_failedProjects.clear(); d->m_depMap.clear(); @@ -1077,6 +1061,9 @@ bool SessionManager::loadSession(const QString &session) d->sessionLoadingProgress(); d->restoreDependencies(reader); d->restoreStartupProject(reader); + + removeProjects(oldProjects); // only remove old projects now that the startup project is set! + d->restoreEditors(reader); d->m_future.reportFinished(); diff --git a/src/plugins/projectexplorer/session.h b/src/plugins/projectexplorer/session.h index a229ce58e1..864bd7c422 100644 --- a/src/plugins/projectexplorer/session.h +++ b/src/plugins/projectexplorer/session.h @@ -78,7 +78,7 @@ public: static void addProject(Project *project); static void removeProject(Project *project); - static void removeProjects(QList<Project *> remove); + static void removeProjects(const QList<Project *> &remove); static void setStartupProject(Project *startupProject); diff --git a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp index 6dc1aa6814..66201cb98b 100644 --- a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp +++ b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp @@ -254,6 +254,10 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor auto archs = architectures(mainTc); if (!archs.isEmpty()) data.insert(QLatin1String(QBS_ARCHITECTURES), archs); + if (mainTc->targetAbi() != + ProjectExplorer::Abi::abiFromTargetTriplet(mainTc->originalTargetTriple())) { + data.insert(QLatin1String(QBS_ARCHITECTURE), architecture(mainTc->targetAbi())); + } data.insert(QLatin1String(QBS_TARGETOS), targetOSList(targetAbi, k)); QStringList toolchain = toolchainList(mainTc); diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 1d0121eab0..eb3191e60e 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -138,17 +138,17 @@ QbsProject::QbsProject(const FileName &fileName) : rebuildProjectTree(); connect(this, &Project::activeTargetChanged, this, &QbsProject::changeActiveTarget); - connect(this, &Project::addedTarget, this, &QbsProject::targetWasAdded); - connect(this, &Project::removedTarget, this, &QbsProject::targetWasRemoved); - subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() { + connect(this, &Project::addedTarget, + this, [this](Target *t) { m_qbsProjects.insert(t, qbs::Project()); }); + connect(this, &Project::removedTarget, + this, [this](Target *t) {m_qbsProjects.remove(t); }); + auto delayedParsing = [this]() { if (static_cast<BuildConfiguration *>(sender())->isActive()) delayParsing(); - }); - connect(this, &Project::activeProjectConfigurationChanged, - this, [this](ProjectConfiguration *pc) { - if (pc && pc->isActive()) - delayParsing(); - }); + }; + subscribeSignal(&BuildConfiguration::environmentChanged, this, delayedParsing); + subscribeSignal(&BuildConfiguration::buildDirectoryChanged, this, delayedParsing); + subscribeSignal(&Target::activeBuildConfigurationChanged, this, delayedParsing); connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing); @@ -540,21 +540,6 @@ void QbsProject::handleRuleExecutionDone() updateAfterParse(); } -void QbsProject::targetWasAdded(Target *t) -{ - m_qbsProjects.insert(t, qbs::Project()); - connect(t, &Target::activeBuildConfigurationChanged, this, &QbsProject::delayParsing); - t->subscribeSignal(&BuildConfiguration::buildDirectoryChanged, this, [this]() { - if (static_cast<BuildConfiguration *>(sender())->isActive()) - delayParsing(); - }); -} - -void QbsProject::targetWasRemoved(Target *t) -{ - m_qbsProjects.remove(t); -} - void QbsProject::changeActiveTarget(Target *t) { BuildConfiguration *bc = 0; diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h index 23e0f706b9..fa12083716 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.h +++ b/src/plugins/qbsprojectmanager/qbsproject.h @@ -118,8 +118,6 @@ private: void rebuildProjectTree(); - void targetWasAdded(ProjectExplorer::Target *t); - void targetWasRemoved(ProjectExplorer::Target *t); void changeActiveTarget(ProjectExplorer::Target *t); void buildConfigurationChanged(ProjectExplorer::BuildConfiguration *bc); void startParsing(); diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h index e53beb84fe..cc6bcd8ed3 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h @@ -78,6 +78,7 @@ const char QBS_PRODUCT_OVERLAY_ICON[] = ":/qbsprojectmanager/images/productgear. const char QBS_TARGETOS[] = "qbs.targetOS"; const char QBS_SYSROOT[] = "qbs.sysroot"; const char QBS_ARCHITECTURES[] = "qbs.architectures"; +const char QBS_ARCHITECTURE[] = "qbs.architecture"; const char QBS_TOOLCHAIN[] = "qbs.toolchain"; const char CPP_TOOLCHAINPATH[] = "cpp.toolchainInstallPath"; const char CPP_TOOLCHAINPREFIX[] = "cpp.toolchainPrefix"; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index a61937d9c3..40b9e55b73 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -28,7 +28,7 @@ #include <QMap> #include <QIcon> #include <QAbstractListModel> -#include <QtQuick> +#include <QtQml/qqml.h> QT_FORWARD_DECLARE_CLASS(QMimeData) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp index 7e36801a83..1ed8d16e1e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp @@ -27,6 +27,8 @@ #include "itemlibraryitem.h" +#include <QDebug> + namespace QmlDesigner { ItemLibrarySectionModel::ItemLibrarySectionModel(QObject *parent) : diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 8e3ef4418a..4364983608 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -41,6 +41,7 @@ #include <metainfo.h> #include "rewritingexception.h" +#include <QDrag> #include <QFileInfo> #include <QFileSystemModel> #include <QStackedWidget> @@ -54,6 +55,7 @@ #include <QApplication> #include <QTimer> #include <QShortcut> +#include <QQmlContext> #include <QQuickItem> namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp index c5bb6e9d12..6937ece5c4 100644 --- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp +++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp @@ -433,7 +433,8 @@ QProcessEnvironment PuppetCreator::processEnvironment() const environment.set(QLatin1String("QML_USE_MOCKUPS"), QLatin1String("true")); environment.set(QLatin1String("QML_PUPPET_MODE"), QLatin1String("true")); environment.set(QLatin1String("QML_DISABLE_DISK_CACHE"), QLatin1String("true")); - environment.set(QLatin1String("QT_AUTO_SCREEN_SCALE_FACTOR"), QLatin1String("1")); + if (!environment.hasKey("QT_SCREEN_SCALE_FACTORS")) + environment.set(QLatin1String("QT_AUTO_SCREEN_SCALE_FACTOR"), QLatin1String("1")); #ifndef QMLDESIGNER_TEST const QString controlsStyle = m_designerSettings.value(DesignerSettingsKey:: diff --git a/src/plugins/qmljseditor/qmljssemantichighlighter.h b/src/plugins/qmljseditor/qmljssemantichighlighter.h index c32a69df89..f1714b7a8e 100644 --- a/src/plugins/qmljseditor/qmljssemantichighlighter.h +++ b/src/plugins/qmljseditor/qmljssemantichighlighter.h @@ -31,7 +31,6 @@ #include <QVector> namespace QmlJS { -class ScopeChain; namespace AST { class SourceLocation; } } diff --git a/src/plugins/qmljstools/qmljsfunctionfilter.cpp b/src/plugins/qmljstools/qmljsfunctionfilter.cpp index 02081f7e90..52577aff99 100644 --- a/src/plugins/qmljstools/qmljsfunctionfilter.cpp +++ b/src/plugins/qmljstools/qmljsfunctionfilter.cpp @@ -28,7 +28,6 @@ #include <coreplugin/editormanager/editormanager.h> #include <utils/algorithm.h> -#include <utils/camelhumpmatcher.h> #include <QRegularExpression> @@ -61,9 +60,8 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor( QList<Core::LocatorFilterEntry> betterEntries; QList<Core::LocatorFilterEntry> bestEntries; const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry); - const QRegularExpression regexp = containsWildcard(entry) - ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry); + const QRegularExpression regexp = createRegExp(entry); if (!regexp.isValid()) return goodEntries; @@ -83,11 +81,8 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor( if (match.hasMatch()) { QVariant id = qVariantFromValue(info); Core::LocatorFilterEntry filterEntry(this, info.displayName, id/*, info.icon*/); - const CamelHumpMatcher::HighlightingPositions positions = - CamelHumpMatcher::highlightingPositions(match); filterEntry.extraInfo = info.extraInfo; - filterEntry.highlightInfo.starts = positions.starts; - filterEntry.highlightInfo.lengths = positions.lengths; + filterEntry.highlightInfo = highlightInfo(match); if (filterEntry.displayName.startsWith(entry, caseSensitivityForPrefix)) bestEntries.append(filterEntry); diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp index f5e182a8e3..f42d3ecc56 100644 --- a/src/plugins/qnx/qnxanalyzesupport.cpp +++ b/src/plugins/qnx/qnxanalyzesupport.cpp @@ -36,76 +36,54 @@ #include <utils/qtcassert.h> #include <utils/qtcprocess.h> + #include <qmldebug/qmldebugcommandlinearguments.h> #include <qmldebug/qmloutputparser.h> +#include <ssh/sshconnection.h> + using namespace ProjectExplorer; using namespace Utils; namespace Qnx { namespace Internal { -class QnxAnalyzeeRunner : public SimpleTargetRunner -{ -public: - QnxAnalyzeeRunner(RunControl *runControl, PortsGatherer *portsGatherer) - : SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer) - { - setDisplayName("QnxAnalyzeeRunner"); - } - -private: - void start() override - { - Utils::Port port = m_portsGatherer->findPort(); - - auto r = runnable().as<StandardRunnable>(); - if (!r.commandLineArguments.isEmpty()) - r.commandLineArguments += ' '; - r.commandLineArguments += - QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, port); - - setRunnable(r); - - SimpleTargetRunner::start(); - } - - PortsGatherer *m_portsGatherer; -}; - - -// QnxDebugSupport - QnxQmlProfilerSupport::QnxQmlProfilerSupport(RunControl *runControl) - : RunWorker(runControl) + : SimpleTargetRunner(runControl) { - runControl->createWorker(runControl->runMode()); - - setDisplayName("QnxAnalyzeSupport"); + setDisplayName("QnxQmlProfilerSupport"); appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat); - auto portsGatherer = new PortsGatherer(runControl); - - auto debuggeeRunner = new QnxAnalyzeeRunner(runControl, portsGatherer); - debuggeeRunner->addStartDependency(portsGatherer); + m_portsGatherer = new PortsGatherer(runControl); + addStartDependency(m_portsGatherer); auto slog2InfoRunner = new Slog2InfoRunner(runControl); - slog2InfoRunner->addStartDependency(debuggeeRunner); - addStartDependency(slog2InfoRunner); - // QmlDebug::QmlOutputParser m_outputParser; - // FIXME: m_outputParser needs to be fed with application output - // connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, - // this, &QnxAnalyzeSupport::remoteIsRunning); - - // m_outputParser.processOutput(msg); + m_profiler = runControl->createWorker(runControl->runMode()); + m_profiler->addStartDependency(this); + addStopDependency(m_profiler); } void QnxQmlProfilerSupport::start() { - // runControl()->notifyRemoteSetupDone(m_qmlPort); - reportStarted(); + Port qmlPort = m_portsGatherer->findPort(); + + QUrl serverUrl; + serverUrl.setHost(device()->sshParameters().host); + serverUrl.setPort(qmlPort.number()); + serverUrl.setScheme("tcp"); + m_profiler->recordData("QmlServerUrl", serverUrl); + + QString args = QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, qmlPort); + auto r = runnable().as<StandardRunnable>(); + if (!r.commandLineArguments.isEmpty()) + r.commandLineArguments.append(' '); + r.commandLineArguments += args; + + setRunnable(r); + + SimpleTargetRunner::start(); } } // namespace Internal diff --git a/src/plugins/qnx/qnxanalyzesupport.h b/src/plugins/qnx/qnxanalyzesupport.h index 9fbd11d0fe..415459e3c1 100644 --- a/src/plugins/qnx/qnxanalyzesupport.h +++ b/src/plugins/qnx/qnxanalyzesupport.h @@ -25,12 +25,13 @@ #pragma once +#include <projectexplorer/devicesupport/deviceusedportsgatherer.h> #include <projectexplorer/runconfiguration.h> namespace Qnx { namespace Internal { -class QnxQmlProfilerSupport : public ProjectExplorer::RunWorker +class QnxQmlProfilerSupport : public ProjectExplorer::SimpleTargetRunner { Q_OBJECT @@ -39,6 +40,9 @@ public: private: void start() override; + + ProjectExplorer::PortsGatherer *m_portsGatherer; + ProjectExplorer::RunWorker *m_profiler; }; } // namespace Internal diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp index cb506420b7..c8339239e0 100644 --- a/src/plugins/qnx/qnxdebugsupport.cpp +++ b/src/plugins/qnx/qnxdebugsupport.cpp @@ -161,6 +161,8 @@ void QnxDebugSupport::start() setRemoteChannel(m_portsGatherer->gdbServerChannel()); setQmlServer(m_portsGatherer->qmlServer()); setSolibSearchPath(searchPaths(k)); + if (auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k))) + setSysRoot(qtVersion->qnxTarget()); setSymbolFile(runConfig->localExecutableFilePath()); DebuggerRunTool::start(); @@ -296,6 +298,8 @@ void QnxAttachDebugSupport::showProcessesDialog() // setRunControlName(tr("Remote: \"%1\" - Process %2").arg(remoteChannel).arg(m_process.pid)); debugger->setRunControlName(tr("Remote QNX process %1").arg(pid)); debugger->setSolibSearchPath(searchPaths(kit)); + if (auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(kit))) + debugger->setSysRoot(qtVersion->qnxTarget()); debugger->setUseContinueInsteadOfRun(true); ProjectExplorerPlugin::startRunControl(runControl); diff --git a/src/plugins/qnx/qnxdevice.cpp b/src/plugins/qnx/qnxdevice.cpp index 31a8d9064d..01d6fec0f4 100644 --- a/src/plugins/qnx/qnxdevice.cpp +++ b/src/plugins/qnx/qnxdevice.cpp @@ -35,6 +35,7 @@ #include <ssh/sshconnection.h> #include <utils/port.h> #include <utils/qtcassert.h> +#include <utils/stringutils.h> #include <QApplication> #include <QRegExp> @@ -59,37 +60,19 @@ class QnxPortsGatheringMethod : public PortsGatheringMethod { Q_UNUSED(protocol); StandardRunnable runnable; - // FIXME: Is this extra shell needed? - runnable.executable = "/bin/sh"; - runnable.commandLineArguments = "-c \"" - "netstat -na " - "| sed 's/[a-z]\\+\\s\\+[0-9]\\+\\s\\+[0-9]\\+\\s\\+\\(\\*\\|[0-9\\.]\\+\\)\\.\\([0-9]\\+\\).*/\\2/g' " - "| while read line; do " - "if [[ $line != udp* ]] && [[ $line != Active* ]]; then " - "printf '%x\n' $line; " - "fi; " - "done" - "\""; + runnable.executable = "netstat"; + runnable.commandLineArguments = "-na"; return runnable; } QList<Port> usedPorts(const QByteArray &output) const override { - QList<Port> ports; - QList<QByteArray> portStrings = output.split('\n'); - portStrings.removeFirst(); - foreach (const QByteArray &portString, portStrings) { - if (portString.isEmpty()) - continue; - bool ok; - const Port port(portString.toInt(&ok, 16)); - if (ok) { - if (!ports.contains(port)) - ports << port; - } else { - qWarning("%s: Unexpected string '%s' is not a port.", - Q_FUNC_INFO, portString.data()); - } + QList<Utils::Port> ports; + const QList<QByteArray> lines = output.split('\n'); + for (const QByteArray &line : lines) { + const Port port(Utils::parseUsedPortFromNetstatOutput(line)); + if (port.isValid() && !ports.contains(port)) + ports.append(port); } return ports; } diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 8a8e00c6c7..e232983f3c 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1768,7 +1768,7 @@ FileNameList BaseQtVersion::qtCorePaths() const if (dir.isEmpty()) continue; QDir d(dir); - QFileInfoList infoList = d.entryInfoList(); + QFileInfoList infoList = d.entryInfoList(QDir::NoDotAndDotDot); foreach (const QFileInfo &info, infoList) { const QString file = info.fileName(); if (info.isDir() diff --git a/src/plugins/subversion/settingspage.h b/src/plugins/subversion/settingspage.h index afb0c6a879..d532394027 100644 --- a/src/plugins/subversion/settingspage.h +++ b/src/plugins/subversion/settingspage.h @@ -33,10 +33,6 @@ #include <QPointer> #include <QString> -QT_BEGIN_NAMESPACE -class QSettings; -QT_END_NAMESPACE - namespace Subversion { namespace Internal { diff --git a/src/plugins/subversion/subversionclient.h b/src/plugins/subversion/subversionclient.h index b3ed32c2c2..aa45c124da 100644 --- a/src/plugins/subversion/subversionclient.h +++ b/src/plugins/subversion/subversionclient.h @@ -25,16 +25,15 @@ #pragma once -#include "subversionsettings.h" #include <vcsbase/vcsbaseclient.h> -#include <vcsbase/vcscommand.h> #include <utils/fileutils.h> +namespace VcsBase { class VcsCommand; } + namespace Subversion { namespace Internal { -class SubversionSettings; class SubversionDiffEditorController; class SubversionClient : public VcsBase::VcsBaseClient diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp index e7265534ea..8bd9e36f37 100644 --- a/src/plugins/subversion/subversioncontrol.cpp +++ b/src/plugins/subversion/subversioncontrol.cpp @@ -32,6 +32,7 @@ #include <vcsbase/vcsbaseconstants.h> #include <vcsbase/vcsbaseclientsettings.h> +#include <vcsbase/vcscommand.h> #include <utils/fileutils.h> diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 80365d7449..0fe63bbc95 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -1274,6 +1274,11 @@ void TextEditorWidgetPrivate::editorContentsChange(int position, int charsRemove // lines were inserted or removed from outside, keep viewport on same part of text if (q->firstVisibleBlock().blockNumber() > posBlock.blockNumber()) q->verticalScrollBar()->setValue(q->verticalScrollBar()->value() + newBlockCount - m_blockCount); + + if (m_inBlockSelectionMode) { + disableBlockSelection(CursorUpdateClearSelection); + q->viewport()->update(); + } } m_blockCount = newBlockCount; m_scrollBarUpdateTimer.start(500); diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index f668ee3a5f..e5821e142f 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -70,6 +70,8 @@ #include <coreplugin/icore.h> #include <coreplugin/id.h> +#include <ssh/sshconnection.h> + #include <utils/fancymainwindow.h> #include <utils/qtcassert.h> #include <utils/utilsicons.h> @@ -78,6 +80,7 @@ #include <QFile> #include <QFileDialog> #include <QFileInfo> +#include <QHostAddress> #include <QLabel> #include <QMenu> #include <QToolButton> diff --git a/src/plugins/winrt/winrtrunnerhelper.cpp b/src/plugins/winrt/winrtrunnerhelper.cpp index 0b4c6653bb..60ca4f870c 100644 --- a/src/plugins/winrt/winrtrunnerhelper.cpp +++ b/src/plugins/winrt/winrtrunnerhelper.cpp @@ -185,7 +185,8 @@ void WinRtRunnerHelper::startWinRtRunner(const RunConf &conf) if (m_device->type() == Constants::WINRT_DEVICE_TYPE_LOCAL) QtcProcess::addArgs(&runnerArgs, QStringLiteral("--profile appx")); - else if (m_device->type() == Constants::WINRT_DEVICE_TYPE_PHONE) + else if (m_device->type() == Constants::WINRT_DEVICE_TYPE_PHONE || + m_device->type() == Constants::WINRT_DEVICE_TYPE_EMULATOR) QtcProcess::addArgs(&runnerArgs, QStringLiteral("--profile appxphone")); QtcProcess::addArg(&runnerArgs, m_executableFilePath); diff --git a/src/shared/proparser/qmakebuiltins.cpp b/src/shared/proparser/qmakebuiltins.cpp index 8808169b14..c2625166cb 100644 --- a/src/shared/proparser/qmakebuiltins.cpp +++ b/src/shared/proparser/qmakebuiltins.cpp @@ -46,6 +46,7 @@ #ifdef PROEVALUATOR_THREAD_SAFE # include <qthreadpool.h> #endif +#include <qversionnumber.h> #include <algorithm> @@ -93,6 +94,7 @@ enum ExpandFunc { enum TestFunc { T_INVALID = 0, T_REQUIRES, T_GREATERTHAN, T_LESSTHAN, T_EQUALS, + T_VERSION_AT_LEAST, T_VERSION_AT_MOST, T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM, T_DEFINED, T_DISCARD_FROM, T_CONTAINS, T_INFILE, T_COUNT, T_ISEMPTY, T_PARSE_JSON, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF, @@ -166,6 +168,8 @@ void QMakeEvaluator::initFunctionStatics() {"lessThan", T_LESSTHAN}, {"equals", T_EQUALS}, {"isEqual", T_EQUALS}, + {"versionAtLeast", T_VERSION_AT_LEAST}, + {"versionAtMost", T_VERSION_AT_MOST}, {"exists", T_EXISTS}, {"export", T_EXPORT}, {"clear", T_CLEAR}, @@ -1492,6 +1496,19 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } return returnBool(values(map(args.at(0))).join(statics.field_sep) == args.at(1).toQString(m_tmp1)); + case T_VERSION_AT_LEAST: + case T_VERSION_AT_MOST: { + if (args.count() != 2) { + evalError(fL1S("%1(variable, versionNumber) requires two arguments.") + .arg(function.toQString(m_tmp1))); + return ReturnFalse; + } + const QVersionNumber lvn = QVersionNumber::fromString(values(args.at(0).toKey()).join('.')); + const QVersionNumber rvn = QVersionNumber::fromString(args.at(1).toQString()); + if (func_t == T_VERSION_AT_LEAST) + return returnBool(lvn >= rvn); + return returnBool(lvn <= rvn); + } case T_CLEAR: { if (args.count() != 1) { evalError(fL1S("%1(variable) requires one argument.") diff --git a/src/shared/qbs b/src/shared/qbs -Subproject 7d85fed02c14d87fbea8a2573f947d2a1ce940a +Subproject 83f43f57ac79fa673fda08805e29763a8303d5e diff --git a/src/tools/clangbackend/clangbackend.pro b/src/tools/clangbackend/clangbackend.pro index b17d923a3b..32ca5f0842 100644 --- a/src/tools/clangbackend/clangbackend.pro +++ b/src/tools/clangbackend/clangbackend.pro @@ -4,7 +4,7 @@ QTC_LIB_DEPENDS += \ include(../../qtcreatortool.pri) include(../../shared/clang/clang_installation.pri) -include(ipcsource/clangbackendclangipc-source.pri) +include(source/clangbackendclangipc-source.pri) QT += core network QT -= gui diff --git a/src/tools/clangbackend/clangbackend.qbs b/src/tools/clangbackend/clangbackend.qbs index 4a1ca11579..495c586f85 100644 --- a/src/tools/clangbackend/clangbackend.qbs +++ b/src/tools/clangbackend/clangbackend.qbs @@ -7,7 +7,7 @@ QtcTool { Depends { name: "libclang"; required: false } Group { - prefix: "ipcsource/" + prefix: "source/" files: [ "*.h", "*.cpp" @@ -26,7 +26,7 @@ QtcTool { condition: libclang.present - cpp.includePaths: base.concat(["ipcsource", libclang.llvmIncludeDir]) + cpp.includePaths: base.concat(["source", libclang.llvmIncludeDir]) cpp.libraryPaths: base.concat(libclang.llvmLibDir) cpp.dynamicLibraries: base.concat(libclang.llvmLibs) cpp.rpaths: base.concat(libclang.llvmLibDir) diff --git a/src/tools/clangbackend/ipcsource/clangasyncjob.h b/src/tools/clangbackend/source/clangasyncjob.h index 58b6a1f845..58b6a1f845 100644 --- a/src/tools/clangbackend/ipcsource/clangasyncjob.h +++ b/src/tools/clangbackend/source/clangasyncjob.h diff --git a/src/tools/clangbackend/ipcsource/clangbackend_global.h b/src/tools/clangbackend/source/clangbackend_global.h index d806afc98c..d806afc98c 100644 --- a/src/tools/clangbackend/ipcsource/clangbackend_global.h +++ b/src/tools/clangbackend/source/clangbackend_global.h diff --git a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri b/src/tools/clangbackend/source/clangbackendclangipc-source.pri index 6919db6839..6919db6839 100644 --- a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri +++ b/src/tools/clangbackend/source/clangbackendclangipc-source.pri diff --git a/src/tools/clangbackend/ipcsource/clangclock.h b/src/tools/clangbackend/source/clangclock.h index 68d91478f7..68d91478f7 100644 --- a/src/tools/clangbackend/ipcsource/clangclock.h +++ b/src/tools/clangbackend/source/clangclock.h diff --git a/src/tools/clangbackend/ipcsource/clangcodecompleteresults.cpp b/src/tools/clangbackend/source/clangcodecompleteresults.cpp index af80d739bf..af80d739bf 100644 --- a/src/tools/clangbackend/ipcsource/clangcodecompleteresults.cpp +++ b/src/tools/clangbackend/source/clangcodecompleteresults.cpp diff --git a/src/tools/clangbackend/ipcsource/clangcodecompleteresults.h b/src/tools/clangbackend/source/clangcodecompleteresults.h index 0b1ae11df8..0b1ae11df8 100644 --- a/src/tools/clangbackend/ipcsource/clangcodecompleteresults.h +++ b/src/tools/clangbackend/source/clangcodecompleteresults.h diff --git a/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp b/src/tools/clangbackend/source/clangcodemodelserver.cpp index 9def46b2db..9def46b2db 100644 --- a/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp +++ b/src/tools/clangbackend/source/clangcodemodelserver.cpp diff --git a/src/tools/clangbackend/ipcsource/clangcodemodelserver.h b/src/tools/clangbackend/source/clangcodemodelserver.h index 5e9e2934a6..5e9e2934a6 100644 --- a/src/tools/clangbackend/ipcsource/clangcodemodelserver.h +++ b/src/tools/clangbackend/source/clangcodemodelserver.h diff --git a/src/tools/clangbackend/ipcsource/clangcompletecodejob.cpp b/src/tools/clangbackend/source/clangcompletecodejob.cpp index 9970d59269..9970d59269 100644 --- a/src/tools/clangbackend/ipcsource/clangcompletecodejob.cpp +++ b/src/tools/clangbackend/source/clangcompletecodejob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangcompletecodejob.h b/src/tools/clangbackend/source/clangcompletecodejob.h index 4e9c274faf..4e9c274faf 100644 --- a/src/tools/clangbackend/ipcsource/clangcompletecodejob.h +++ b/src/tools/clangbackend/source/clangcompletecodejob.h diff --git a/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.cpp b/src/tools/clangbackend/source/clangcreateinitialdocumentpreamblejob.cpp index aab58b0edb..aab58b0edb 100644 --- a/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.cpp +++ b/src/tools/clangbackend/source/clangcreateinitialdocumentpreamblejob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.h b/src/tools/clangbackend/source/clangcreateinitialdocumentpreamblejob.h index f8b790ea36..f8b790ea36 100644 --- a/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.h +++ b/src/tools/clangbackend/source/clangcreateinitialdocumentpreamblejob.h diff --git a/src/tools/clangbackend/ipcsource/clangdocument.cpp b/src/tools/clangbackend/source/clangdocument.cpp index cbbaf51b33..cbbaf51b33 100644 --- a/src/tools/clangbackend/ipcsource/clangdocument.cpp +++ b/src/tools/clangbackend/source/clangdocument.cpp diff --git a/src/tools/clangbackend/ipcsource/clangdocument.h b/src/tools/clangbackend/source/clangdocument.h index 415deefbe9..415deefbe9 100644 --- a/src/tools/clangbackend/ipcsource/clangdocument.h +++ b/src/tools/clangbackend/source/clangdocument.h diff --git a/src/tools/clangbackend/ipcsource/clangdocumentjob.h b/src/tools/clangbackend/source/clangdocumentjob.h index 7808286ce0..7808286ce0 100644 --- a/src/tools/clangbackend/ipcsource/clangdocumentjob.h +++ b/src/tools/clangbackend/source/clangdocumentjob.h diff --git a/src/tools/clangbackend/ipcsource/clangdocumentprocessor.cpp b/src/tools/clangbackend/source/clangdocumentprocessor.cpp index 1aa5906214..1aa5906214 100644 --- a/src/tools/clangbackend/ipcsource/clangdocumentprocessor.cpp +++ b/src/tools/clangbackend/source/clangdocumentprocessor.cpp diff --git a/src/tools/clangbackend/ipcsource/clangdocumentprocessor.h b/src/tools/clangbackend/source/clangdocumentprocessor.h index 9c3fb147f9..9c3fb147f9 100644 --- a/src/tools/clangbackend/ipcsource/clangdocumentprocessor.h +++ b/src/tools/clangbackend/source/clangdocumentprocessor.h diff --git a/src/tools/clangbackend/ipcsource/clangdocumentprocessors.cpp b/src/tools/clangbackend/source/clangdocumentprocessors.cpp index 611611a41f..611611a41f 100644 --- a/src/tools/clangbackend/ipcsource/clangdocumentprocessors.cpp +++ b/src/tools/clangbackend/source/clangdocumentprocessors.cpp diff --git a/src/tools/clangbackend/ipcsource/clangdocumentprocessors.h b/src/tools/clangbackend/source/clangdocumentprocessors.h index 83e37f5276..83e37f5276 100644 --- a/src/tools/clangbackend/ipcsource/clangdocumentprocessors.h +++ b/src/tools/clangbackend/source/clangdocumentprocessors.h diff --git a/src/tools/clangbackend/ipcsource/clangdocuments.cpp b/src/tools/clangbackend/source/clangdocuments.cpp index 5fc8f294a7..5fc8f294a7 100644 --- a/src/tools/clangbackend/ipcsource/clangdocuments.cpp +++ b/src/tools/clangbackend/source/clangdocuments.cpp diff --git a/src/tools/clangbackend/ipcsource/clangdocuments.h b/src/tools/clangbackend/source/clangdocuments.h index a267becc27..a267becc27 100644 --- a/src/tools/clangbackend/ipcsource/clangdocuments.h +++ b/src/tools/clangbackend/source/clangdocuments.h diff --git a/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp b/src/tools/clangbackend/source/clangdocumentsuspenderresumer.cpp index cd0e29b5d0..cd0e29b5d0 100644 --- a/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp +++ b/src/tools/clangbackend/source/clangdocumentsuspenderresumer.cpp diff --git a/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.h b/src/tools/clangbackend/source/clangdocumentsuspenderresumer.h index 7e2bd8722d..7e2bd8722d 100644 --- a/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.h +++ b/src/tools/clangbackend/source/clangdocumentsuspenderresumer.h diff --git a/src/tools/clangbackend/ipcsource/clangexceptions.cpp b/src/tools/clangbackend/source/clangexceptions.cpp index 62527b6ce7..62527b6ce7 100644 --- a/src/tools/clangbackend/ipcsource/clangexceptions.cpp +++ b/src/tools/clangbackend/source/clangexceptions.cpp diff --git a/src/tools/clangbackend/ipcsource/clangexceptions.h b/src/tools/clangbackend/source/clangexceptions.h index ffc1c09da1..ffc1c09da1 100644 --- a/src/tools/clangbackend/ipcsource/clangexceptions.h +++ b/src/tools/clangbackend/source/clangexceptions.h diff --git a/src/tools/clangbackend/ipcsource/clangfilepath.cpp b/src/tools/clangbackend/source/clangfilepath.cpp index a5fc26b11d..a5fc26b11d 100644 --- a/src/tools/clangbackend/ipcsource/clangfilepath.cpp +++ b/src/tools/clangbackend/source/clangfilepath.cpp diff --git a/src/tools/clangbackend/ipcsource/clangfilepath.h b/src/tools/clangbackend/source/clangfilepath.h index 014c0129ed..014c0129ed 100644 --- a/src/tools/clangbackend/ipcsource/clangfilepath.h +++ b/src/tools/clangbackend/source/clangfilepath.h diff --git a/src/tools/clangbackend/ipcsource/clangfilesystemwatcher.cpp b/src/tools/clangbackend/source/clangfilesystemwatcher.cpp index a51676abe0..a51676abe0 100644 --- a/src/tools/clangbackend/ipcsource/clangfilesystemwatcher.cpp +++ b/src/tools/clangbackend/source/clangfilesystemwatcher.cpp diff --git a/src/tools/clangbackend/ipcsource/clangfilesystemwatcher.h b/src/tools/clangbackend/source/clangfilesystemwatcher.h index 549870eab0..549870eab0 100644 --- a/src/tools/clangbackend/ipcsource/clangfilesystemwatcher.h +++ b/src/tools/clangbackend/source/clangfilesystemwatcher.h diff --git a/src/tools/clangbackend/ipcsource/clangfollowsymbol.cpp b/src/tools/clangbackend/source/clangfollowsymbol.cpp index bc151bc93c..bc151bc93c 100644 --- a/src/tools/clangbackend/ipcsource/clangfollowsymbol.cpp +++ b/src/tools/clangbackend/source/clangfollowsymbol.cpp diff --git a/src/tools/clangbackend/ipcsource/clangfollowsymbol.h b/src/tools/clangbackend/source/clangfollowsymbol.h index a881bd9631..a881bd9631 100644 --- a/src/tools/clangbackend/ipcsource/clangfollowsymbol.h +++ b/src/tools/clangbackend/source/clangfollowsymbol.h diff --git a/src/tools/clangbackend/ipcsource/clangfollowsymboljob.cpp b/src/tools/clangbackend/source/clangfollowsymboljob.cpp index 7136db3432..7136db3432 100644 --- a/src/tools/clangbackend/ipcsource/clangfollowsymboljob.cpp +++ b/src/tools/clangbackend/source/clangfollowsymboljob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangfollowsymboljob.h b/src/tools/clangbackend/source/clangfollowsymboljob.h index 3a8741db1c..3a8741db1c 100644 --- a/src/tools/clangbackend/ipcsource/clangfollowsymboljob.h +++ b/src/tools/clangbackend/source/clangfollowsymboljob.h diff --git a/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp b/src/tools/clangbackend/source/clangiasyncjob.cpp index c325c494c9..c325c494c9 100644 --- a/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp +++ b/src/tools/clangbackend/source/clangiasyncjob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangiasyncjob.h b/src/tools/clangbackend/source/clangiasyncjob.h index e4481fcbf5..e4481fcbf5 100644 --- a/src/tools/clangbackend/ipcsource/clangiasyncjob.h +++ b/src/tools/clangbackend/source/clangiasyncjob.h diff --git a/src/tools/clangbackend/ipcsource/clangjobcontext.cpp b/src/tools/clangbackend/source/clangjobcontext.cpp index e0eb444a94..e0eb444a94 100644 --- a/src/tools/clangbackend/ipcsource/clangjobcontext.cpp +++ b/src/tools/clangbackend/source/clangjobcontext.cpp diff --git a/src/tools/clangbackend/ipcsource/clangjobcontext.h b/src/tools/clangbackend/source/clangjobcontext.h index 629d8320bd..629d8320bd 100644 --- a/src/tools/clangbackend/ipcsource/clangjobcontext.h +++ b/src/tools/clangbackend/source/clangjobcontext.h diff --git a/src/tools/clangbackend/ipcsource/clangjobqueue.cpp b/src/tools/clangbackend/source/clangjobqueue.cpp index 4ea098db3a..4ea098db3a 100644 --- a/src/tools/clangbackend/ipcsource/clangjobqueue.cpp +++ b/src/tools/clangbackend/source/clangjobqueue.cpp diff --git a/src/tools/clangbackend/ipcsource/clangjobqueue.h b/src/tools/clangbackend/source/clangjobqueue.h index 0d9c49ef04..0d9c49ef04 100644 --- a/src/tools/clangbackend/ipcsource/clangjobqueue.h +++ b/src/tools/clangbackend/source/clangjobqueue.h diff --git a/src/tools/clangbackend/ipcsource/clangjobrequest.cpp b/src/tools/clangbackend/source/clangjobrequest.cpp index 9f8eb55f77..9f8eb55f77 100644 --- a/src/tools/clangbackend/ipcsource/clangjobrequest.cpp +++ b/src/tools/clangbackend/source/clangjobrequest.cpp diff --git a/src/tools/clangbackend/ipcsource/clangjobrequest.h b/src/tools/clangbackend/source/clangjobrequest.h index 78aaed6618..78aaed6618 100644 --- a/src/tools/clangbackend/ipcsource/clangjobrequest.h +++ b/src/tools/clangbackend/source/clangjobrequest.h diff --git a/src/tools/clangbackend/ipcsource/clangjobs.cpp b/src/tools/clangbackend/source/clangjobs.cpp index 033dc4ef1a..033dc4ef1a 100644 --- a/src/tools/clangbackend/ipcsource/clangjobs.cpp +++ b/src/tools/clangbackend/source/clangjobs.cpp diff --git a/src/tools/clangbackend/ipcsource/clangjobs.h b/src/tools/clangbackend/source/clangjobs.h index d154d401e8..d154d401e8 100644 --- a/src/tools/clangbackend/ipcsource/clangjobs.h +++ b/src/tools/clangbackend/source/clangjobs.h diff --git a/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.cpp b/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.cpp index 017426ab02..017426ab02 100644 --- a/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.cpp +++ b/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.h b/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.h index 5a0cfec183..5a0cfec183 100644 --- a/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.h +++ b/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.h diff --git a/src/tools/clangbackend/ipcsource/clangreferencescollector.cpp b/src/tools/clangbackend/source/clangreferencescollector.cpp index d2b7bf5431..d2b7bf5431 100644 --- a/src/tools/clangbackend/ipcsource/clangreferencescollector.cpp +++ b/src/tools/clangbackend/source/clangreferencescollector.cpp diff --git a/src/tools/clangbackend/ipcsource/clangreferencescollector.h b/src/tools/clangbackend/source/clangreferencescollector.h index 263ba07fd9..263ba07fd9 100644 --- a/src/tools/clangbackend/ipcsource/clangreferencescollector.h +++ b/src/tools/clangbackend/source/clangreferencescollector.h diff --git a/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.cpp b/src/tools/clangbackend/source/clangreparsesupportivetranslationunitjob.cpp index a02821fff4..a02821fff4 100644 --- a/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.cpp +++ b/src/tools/clangbackend/source/clangreparsesupportivetranslationunitjob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.h b/src/tools/clangbackend/source/clangreparsesupportivetranslationunitjob.h index cb146299c7..cb146299c7 100644 --- a/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.h +++ b/src/tools/clangbackend/source/clangreparsesupportivetranslationunitjob.h diff --git a/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.cpp b/src/tools/clangbackend/source/clangrequestdocumentannotationsjob.cpp index 99ac98eec2..99ac98eec2 100644 --- a/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.cpp +++ b/src/tools/clangbackend/source/clangrequestdocumentannotationsjob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.h b/src/tools/clangbackend/source/clangrequestdocumentannotationsjob.h index 1c78621119..1c78621119 100644 --- a/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.h +++ b/src/tools/clangbackend/source/clangrequestdocumentannotationsjob.h diff --git a/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.cpp b/src/tools/clangbackend/source/clangrequestreferencesjob.cpp index 39b3319488..39b3319488 100644 --- a/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.cpp +++ b/src/tools/clangbackend/source/clangrequestreferencesjob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.h b/src/tools/clangbackend/source/clangrequestreferencesjob.h index d92d869a9b..d92d869a9b 100644 --- a/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.h +++ b/src/tools/clangbackend/source/clangrequestreferencesjob.h diff --git a/src/tools/clangbackend/ipcsource/clangresumedocumentjob.cpp b/src/tools/clangbackend/source/clangresumedocumentjob.cpp index c628d4444a..c628d4444a 100644 --- a/src/tools/clangbackend/ipcsource/clangresumedocumentjob.cpp +++ b/src/tools/clangbackend/source/clangresumedocumentjob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangresumedocumentjob.h b/src/tools/clangbackend/source/clangresumedocumentjob.h index aff8e780f7..aff8e780f7 100644 --- a/src/tools/clangbackend/ipcsource/clangresumedocumentjob.h +++ b/src/tools/clangbackend/source/clangresumedocumentjob.h diff --git a/src/tools/clangbackend/ipcsource/clangstring.h b/src/tools/clangbackend/source/clangstring.h index 685055cff0..685055cff0 100644 --- a/src/tools/clangbackend/ipcsource/clangstring.h +++ b/src/tools/clangbackend/source/clangstring.h diff --git a/src/tools/clangbackend/ipcsource/clangsupportivetranslationunitinitializer.cpp b/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp index 9c162eb8cf..9c162eb8cf 100644 --- a/src/tools/clangbackend/ipcsource/clangsupportivetranslationunitinitializer.cpp +++ b/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp diff --git a/src/tools/clangbackend/ipcsource/clangsupportivetranslationunitinitializer.h b/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.h index 18a01864dd..18a01864dd 100644 --- a/src/tools/clangbackend/ipcsource/clangsupportivetranslationunitinitializer.h +++ b/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.h diff --git a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp b/src/tools/clangbackend/source/clangsuspenddocumentjob.cpp index 87fe54bfae..87fe54bfae 100644 --- a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp +++ b/src/tools/clangbackend/source/clangsuspenddocumentjob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h b/src/tools/clangbackend/source/clangsuspenddocumentjob.h index 5948f8226f..5948f8226f 100644 --- a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h +++ b/src/tools/clangbackend/source/clangsuspenddocumentjob.h diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp b/src/tools/clangbackend/source/clangtranslationunit.cpp index 720bfb9255..720bfb9255 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp +++ b/src/tools/clangbackend/source/clangtranslationunit.cpp diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.h b/src/tools/clangbackend/source/clangtranslationunit.h index 9634c8cb51..9634c8cb51 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunit.h +++ b/src/tools/clangbackend/source/clangtranslationunit.h diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunits.cpp b/src/tools/clangbackend/source/clangtranslationunits.cpp index 432da3d02c..432da3d02c 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunits.cpp +++ b/src/tools/clangbackend/source/clangtranslationunits.cpp diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunits.h b/src/tools/clangbackend/source/clangtranslationunits.h index e89d0ebd25..e89d0ebd25 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunits.h +++ b/src/tools/clangbackend/source/clangtranslationunits.h diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunitupdater.cpp b/src/tools/clangbackend/source/clangtranslationunitupdater.cpp index ade9cb35f9..ade9cb35f9 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunitupdater.cpp +++ b/src/tools/clangbackend/source/clangtranslationunitupdater.cpp diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunitupdater.h b/src/tools/clangbackend/source/clangtranslationunitupdater.h index 547c6838bc..547c6838bc 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunitupdater.h +++ b/src/tools/clangbackend/source/clangtranslationunitupdater.h diff --git a/src/tools/clangbackend/ipcsource/clangtype.cpp b/src/tools/clangbackend/source/clangtype.cpp index 8fc09d8c4a..8fc09d8c4a 100644 --- a/src/tools/clangbackend/ipcsource/clangtype.cpp +++ b/src/tools/clangbackend/source/clangtype.cpp diff --git a/src/tools/clangbackend/ipcsource/clangtype.h b/src/tools/clangbackend/source/clangtype.h index f26fe080f6..f26fe080f6 100644 --- a/src/tools/clangbackend/ipcsource/clangtype.h +++ b/src/tools/clangbackend/source/clangtype.h diff --git a/src/tools/clangbackend/ipcsource/clangunsavedfilesshallowarguments.cpp b/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.cpp index 6fe23d606f..6fe23d606f 100644 --- a/src/tools/clangbackend/ipcsource/clangunsavedfilesshallowarguments.cpp +++ b/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.cpp diff --git a/src/tools/clangbackend/ipcsource/clangunsavedfilesshallowarguments.h b/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.h index 20c8981ef2..20c8981ef2 100644 --- a/src/tools/clangbackend/ipcsource/clangunsavedfilesshallowarguments.h +++ b/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.h diff --git a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp b/src/tools/clangbackend/source/clangupdatedocumentannotationsjob.cpp index 7333ca6878..7333ca6878 100644 --- a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp +++ b/src/tools/clangbackend/source/clangupdatedocumentannotationsjob.cpp diff --git a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h b/src/tools/clangbackend/source/clangupdatedocumentannotationsjob.h index 141b3535a0..141b3535a0 100644 --- a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h +++ b/src/tools/clangbackend/source/clangupdatedocumentannotationsjob.h diff --git a/src/tools/clangbackend/ipcsource/codecompleter.cpp b/src/tools/clangbackend/source/codecompleter.cpp index 8fa5c9cce2..8fa5c9cce2 100644 --- a/src/tools/clangbackend/ipcsource/codecompleter.cpp +++ b/src/tools/clangbackend/source/codecompleter.cpp diff --git a/src/tools/clangbackend/ipcsource/codecompleter.h b/src/tools/clangbackend/source/codecompleter.h index 2026e9ba2c..2026e9ba2c 100644 --- a/src/tools/clangbackend/ipcsource/codecompleter.h +++ b/src/tools/clangbackend/source/codecompleter.h diff --git a/src/tools/clangbackend/ipcsource/codecompletionchunkconverter.cpp b/src/tools/clangbackend/source/codecompletionchunkconverter.cpp index 76c578643f..76c578643f 100644 --- a/src/tools/clangbackend/ipcsource/codecompletionchunkconverter.cpp +++ b/src/tools/clangbackend/source/codecompletionchunkconverter.cpp diff --git a/src/tools/clangbackend/ipcsource/codecompletionchunkconverter.h b/src/tools/clangbackend/source/codecompletionchunkconverter.h index 0bfb1a19c1..0bfb1a19c1 100644 --- a/src/tools/clangbackend/ipcsource/codecompletionchunkconverter.h +++ b/src/tools/clangbackend/source/codecompletionchunkconverter.h diff --git a/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp b/src/tools/clangbackend/source/codecompletionsextractor.cpp index 89dec4b1bf..89dec4b1bf 100644 --- a/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp +++ b/src/tools/clangbackend/source/codecompletionsextractor.cpp diff --git a/src/tools/clangbackend/ipcsource/codecompletionsextractor.h b/src/tools/clangbackend/source/codecompletionsextractor.h index bbb3611bf6..bbb3611bf6 100644 --- a/src/tools/clangbackend/ipcsource/codecompletionsextractor.h +++ b/src/tools/clangbackend/source/codecompletionsextractor.h diff --git a/src/tools/clangbackend/ipcsource/commandlinearguments.cpp b/src/tools/clangbackend/source/commandlinearguments.cpp index a7f29b870f..a7f29b870f 100644 --- a/src/tools/clangbackend/ipcsource/commandlinearguments.cpp +++ b/src/tools/clangbackend/source/commandlinearguments.cpp diff --git a/src/tools/clangbackend/ipcsource/commandlinearguments.h b/src/tools/clangbackend/source/commandlinearguments.h index aa0b2bafbf..aa0b2bafbf 100644 --- a/src/tools/clangbackend/ipcsource/commandlinearguments.h +++ b/src/tools/clangbackend/source/commandlinearguments.h diff --git a/src/tools/clangbackend/ipcsource/cursor.cpp b/src/tools/clangbackend/source/cursor.cpp index 6ad50307cd..6ad50307cd 100644 --- a/src/tools/clangbackend/ipcsource/cursor.cpp +++ b/src/tools/clangbackend/source/cursor.cpp diff --git a/src/tools/clangbackend/ipcsource/cursor.h b/src/tools/clangbackend/source/cursor.h index 6520366b36..6520366b36 100644 --- a/src/tools/clangbackend/ipcsource/cursor.h +++ b/src/tools/clangbackend/source/cursor.h diff --git a/src/tools/clangbackend/ipcsource/diagnostic.cpp b/src/tools/clangbackend/source/diagnostic.cpp index 5e74970ac2..5e74970ac2 100644 --- a/src/tools/clangbackend/ipcsource/diagnostic.cpp +++ b/src/tools/clangbackend/source/diagnostic.cpp diff --git a/src/tools/clangbackend/ipcsource/diagnostic.h b/src/tools/clangbackend/source/diagnostic.h index 140322931f..140322931f 100644 --- a/src/tools/clangbackend/ipcsource/diagnostic.h +++ b/src/tools/clangbackend/source/diagnostic.h diff --git a/src/tools/clangbackend/ipcsource/diagnosticset.cpp b/src/tools/clangbackend/source/diagnosticset.cpp index ce3504a114..ce3504a114 100644 --- a/src/tools/clangbackend/ipcsource/diagnosticset.cpp +++ b/src/tools/clangbackend/source/diagnosticset.cpp diff --git a/src/tools/clangbackend/ipcsource/diagnosticset.h b/src/tools/clangbackend/source/diagnosticset.h index e715ad2627..e715ad2627 100644 --- a/src/tools/clangbackend/ipcsource/diagnosticset.h +++ b/src/tools/clangbackend/source/diagnosticset.h diff --git a/src/tools/clangbackend/ipcsource/diagnosticsetiterator.h b/src/tools/clangbackend/source/diagnosticsetiterator.h index 7739dfd365..7739dfd365 100644 --- a/src/tools/clangbackend/ipcsource/diagnosticsetiterator.h +++ b/src/tools/clangbackend/source/diagnosticsetiterator.h diff --git a/src/tools/clangbackend/ipcsource/fixit.cpp b/src/tools/clangbackend/source/fixit.cpp index c2de39c922..c2de39c922 100644 --- a/src/tools/clangbackend/ipcsource/fixit.cpp +++ b/src/tools/clangbackend/source/fixit.cpp diff --git a/src/tools/clangbackend/ipcsource/fixit.h b/src/tools/clangbackend/source/fixit.h index f866bc8c18..f866bc8c18 100644 --- a/src/tools/clangbackend/ipcsource/fixit.h +++ b/src/tools/clangbackend/source/fixit.h diff --git a/src/tools/clangbackend/ipcsource/highlightingmark.cpp b/src/tools/clangbackend/source/highlightingmark.cpp index 9339d4ba9e..9339d4ba9e 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmark.cpp +++ b/src/tools/clangbackend/source/highlightingmark.cpp diff --git a/src/tools/clangbackend/ipcsource/highlightingmark.h b/src/tools/clangbackend/source/highlightingmark.h index b322391c49..b322391c49 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmark.h +++ b/src/tools/clangbackend/source/highlightingmark.h diff --git a/src/tools/clangbackend/ipcsource/highlightingmarks.cpp b/src/tools/clangbackend/source/highlightingmarks.cpp index ed8ddfdd65..ed8ddfdd65 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmarks.cpp +++ b/src/tools/clangbackend/source/highlightingmarks.cpp diff --git a/src/tools/clangbackend/ipcsource/highlightingmarks.h b/src/tools/clangbackend/source/highlightingmarks.h index e573dc267e..e573dc267e 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmarks.h +++ b/src/tools/clangbackend/source/highlightingmarks.h diff --git a/src/tools/clangbackend/ipcsource/highlightingmarksiterator.h b/src/tools/clangbackend/source/highlightingmarksiterator.h index daeada47a7..daeada47a7 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmarksiterator.h +++ b/src/tools/clangbackend/source/highlightingmarksiterator.h diff --git a/src/tools/clangbackend/ipcsource/projectpart.cpp b/src/tools/clangbackend/source/projectpart.cpp index 4ea8db6609..4ea8db6609 100644 --- a/src/tools/clangbackend/ipcsource/projectpart.cpp +++ b/src/tools/clangbackend/source/projectpart.cpp diff --git a/src/tools/clangbackend/ipcsource/projectpart.h b/src/tools/clangbackend/source/projectpart.h index b96089d283..b96089d283 100644 --- a/src/tools/clangbackend/ipcsource/projectpart.h +++ b/src/tools/clangbackend/source/projectpart.h diff --git a/src/tools/clangbackend/ipcsource/projects.cpp b/src/tools/clangbackend/source/projects.cpp index 1a28b9e785..1a28b9e785 100644 --- a/src/tools/clangbackend/ipcsource/projects.cpp +++ b/src/tools/clangbackend/source/projects.cpp diff --git a/src/tools/clangbackend/ipcsource/projects.h b/src/tools/clangbackend/source/projects.h index 4354aebbeb..4354aebbeb 100644 --- a/src/tools/clangbackend/ipcsource/projects.h +++ b/src/tools/clangbackend/source/projects.h diff --git a/src/tools/clangbackend/ipcsource/skippedsourceranges.cpp b/src/tools/clangbackend/source/skippedsourceranges.cpp index ca38510cf2..ca38510cf2 100644 --- a/src/tools/clangbackend/ipcsource/skippedsourceranges.cpp +++ b/src/tools/clangbackend/source/skippedsourceranges.cpp diff --git a/src/tools/clangbackend/ipcsource/skippedsourceranges.h b/src/tools/clangbackend/source/skippedsourceranges.h index 80bc943676..80bc943676 100644 --- a/src/tools/clangbackend/ipcsource/skippedsourceranges.h +++ b/src/tools/clangbackend/source/skippedsourceranges.h diff --git a/src/tools/clangbackend/ipcsource/sourcelocation.cpp b/src/tools/clangbackend/source/sourcelocation.cpp index 161ed5b0a5..161ed5b0a5 100644 --- a/src/tools/clangbackend/ipcsource/sourcelocation.cpp +++ b/src/tools/clangbackend/source/sourcelocation.cpp diff --git a/src/tools/clangbackend/ipcsource/sourcelocation.h b/src/tools/clangbackend/source/sourcelocation.h index 65c3ec69ad..65c3ec69ad 100644 --- a/src/tools/clangbackend/ipcsource/sourcelocation.h +++ b/src/tools/clangbackend/source/sourcelocation.h diff --git a/src/tools/clangbackend/ipcsource/sourcerange.cpp b/src/tools/clangbackend/source/sourcerange.cpp index 20c6efb5e6..20c6efb5e6 100644 --- a/src/tools/clangbackend/ipcsource/sourcerange.cpp +++ b/src/tools/clangbackend/source/sourcerange.cpp diff --git a/src/tools/clangbackend/ipcsource/sourcerange.h b/src/tools/clangbackend/source/sourcerange.h index b8083e8695..b8083e8695 100644 --- a/src/tools/clangbackend/ipcsource/sourcerange.h +++ b/src/tools/clangbackend/source/sourcerange.h diff --git a/src/tools/clangbackend/ipcsource/unsavedfile.cpp b/src/tools/clangbackend/source/unsavedfile.cpp index 923d4456e8..923d4456e8 100644 --- a/src/tools/clangbackend/ipcsource/unsavedfile.cpp +++ b/src/tools/clangbackend/source/unsavedfile.cpp diff --git a/src/tools/clangbackend/ipcsource/unsavedfile.h b/src/tools/clangbackend/source/unsavedfile.h index 3021da89b5..3021da89b5 100644 --- a/src/tools/clangbackend/ipcsource/unsavedfile.h +++ b/src/tools/clangbackend/source/unsavedfile.h diff --git a/src/tools/clangbackend/ipcsource/unsavedfiles.cpp b/src/tools/clangbackend/source/unsavedfiles.cpp index 64f2afe3ff..64f2afe3ff 100644 --- a/src/tools/clangbackend/ipcsource/unsavedfiles.cpp +++ b/src/tools/clangbackend/source/unsavedfiles.cpp diff --git a/src/tools/clangbackend/ipcsource/unsavedfiles.h b/src/tools/clangbackend/source/unsavedfiles.h index eacab0bc34..eacab0bc34 100644 --- a/src/tools/clangbackend/ipcsource/unsavedfiles.h +++ b/src/tools/clangbackend/source/unsavedfiles.h diff --git a/src/tools/clangbackend/ipcsource/utf8positionfromlinecolumn.cpp b/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp index 1d7ea1a88f..1d7ea1a88f 100644 --- a/src/tools/clangbackend/ipcsource/utf8positionfromlinecolumn.cpp +++ b/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp diff --git a/src/tools/clangbackend/ipcsource/utf8positionfromlinecolumn.h b/src/tools/clangbackend/source/utf8positionfromlinecolumn.h index facb152772..facb152772 100644 --- a/src/tools/clangbackend/ipcsource/utf8positionfromlinecolumn.h +++ b/src/tools/clangbackend/source/utf8positionfromlinecolumn.h diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index 297f6aaff1..1703885bc5 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -7980,9 +7980,9 @@ <circle style="fill:#000000" id="path4864-5" - cx="962.5" - cy="577.5" - r="5.5" /> + cx="963" + cy="578" + r="5" /> </g> <g id="src/libs/utils/images/iconoverlay_add" diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 76bd2fe221..115bdc68a0 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -37,6 +37,8 @@ #endif // Q_CC_MSVC #endif // Q_OS_WIN +#include <utils/asconst.h> + #include <QtTest> #include <math.h> @@ -58,7 +60,7 @@ static bool generateEnvironmentSettings(Utils::Environment &env, // Note, can't just use a QTemporaryFile all the way through as it remains open // internally so it can't be streamed to later. QString tempOutFile; - QTemporaryFile* pVarsTempFile = new QTemporaryFile(QDir::tempPath() + QLatin1String("/XXXXXX.txt")); + QTemporaryFile* pVarsTempFile = new QTemporaryFile(QDir::tempPath() + "/XXXXXX.txt"); pVarsTempFile->setAutoRemove(false); pVarsTempFile->open(); pVarsTempFile->close(); @@ -66,7 +68,7 @@ static bool generateEnvironmentSettings(Utils::Environment &env, delete pVarsTempFile; // Create a batch file to create and save the env settings - Utils::TempFileSaver saver(QDir::tempPath() + QLatin1String("/XXXXXX.bat")); + Utils::TempFileSaver saver(QDir::tempPath() + "/XXXXXX.bat"); QByteArray call = "call "; call += Utils::QtcProcess::quoteArg(batchFile).toLocal8Bit(); @@ -88,13 +90,11 @@ static bool generateEnvironmentSettings(Utils::Environment &env, // As of WinSDK 7.1, there is logic preventing the path from being set // correctly if "ORIGINALPATH" is already set. That can cause problems // if Creator is launched within a session set up by setenv.cmd. - env.unset(QLatin1String("ORIGINALPATH")); + env.unset("ORIGINALPATH"); run.setEnvironment(env); const QString cmdPath = QString::fromLocal8Bit(qgetenv("COMSPEC")); // Windows SDK setup scripts require command line switches for environment expansion. - QString cmdArguments = QLatin1String(" /E:ON /V:ON /c \""); - cmdArguments += QDir::toNativeSeparators(saver.fileName()); - cmdArguments += QLatin1Char('"'); + QString cmdArguments = " /E:ON /V:ON /c \"" + QDir::toNativeSeparators(saver.fileName()) + '"'; run.setCommand(cmdPath, cmdArguments); run.start(); @@ -119,7 +119,7 @@ static bool generateEnvironmentSettings(Utils::Environment &env, if (!varsFile.open(QIODevice::ReadOnly)) return false; - QRegExp regexp(QLatin1String("(\\w*)=(.*)")); + QRegExp regexp("(\\w*)=(.*)"); while (!varsFile.atEnd()) { const QString line = QString::fromLocal8Bit(varsFile.readLine()).trimmed(); if (regexp.exactMatch(line)) { @@ -282,7 +282,7 @@ static QString parentIName(const QString &iname) struct Value { Value() : value(noValue) {} - Value(const char *str) : value(QLatin1String(str)) {} + Value(const char *str) : value(str) {} Value(const QString &str) : value(str) {} bool matches(const QString &actualValue0, const Context &context) const @@ -959,11 +959,9 @@ public: struct TempStuff { - TempStuff(const char *tag) : buildTemp(QLatin1String("qt_tst_dumpers_") - + QLatin1String(tag) - + QLatin1Char('_')) + TempStuff(const char *tag) : buildTemp(QString("qt_tst_dumpers_") + tag + '_') { - buildPath = QDir::currentPath() + QLatin1Char('/') + buildTemp.path(); + buildPath = QDir::currentPath() + '/' + buildTemp.path(); buildTemp.setAutoRemove(false); QVERIFY(!buildPath.isEmpty()); } @@ -1030,7 +1028,7 @@ void tst_Dumpers::initTestCase() if (base.startsWith("lldb")) m_debuggerEngine = LldbEngine; - m_qmakeBinary = QString::fromLocal8Bit(qgetenv("QTC_QMAKE_PATH_FOR_TEST")); + m_qmakeBinary = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv("QTC_QMAKE_PATH_FOR_TEST"))); if (m_qmakeBinary.isEmpty()) m_qmakeBinary = "qmake"; qDebug() << "QMake : " << m_qmakeBinary; @@ -1043,7 +1041,7 @@ void tst_Dumpers::initTestCase() if (m_debuggerEngine == GdbEngine) { QProcess debugger; - debugger.start(m_debuggerBinary + " -i mi -quiet -nx"); + debugger.start(m_debuggerBinary, {"-i", "mi", "-quiet", "-nx"}); bool ok = debugger.waitForStarted(); debugger.write("set confirm off\npython print 43\nshow version\nquit\n"); ok = debugger.waitForFinished(); @@ -1065,18 +1063,19 @@ void tst_Dumpers::initTestCase() version = version.mid(pos1, pos2 - pos1); extractGdbVersion(version, &m_debuggerVersion, &m_gdbBuildVersion, &m_isMacGdb, &m_isQnxGdb); - m_env = QProcessEnvironment::systemEnvironment(); - m_makeBinary = QString::fromLocal8Bit(qgetenv("QTC_MAKE_PATH_FOR_TEST")); + m_makeBinary = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv("QTC_MAKE_PATH_FOR_TEST"))); #ifdef Q_OS_WIN + Utils::Environment env = Utils::Environment::systemEnvironment(); if (m_makeBinary.isEmpty()) m_makeBinary = "mingw32-make"; + if (m_makeBinary != "mingw32-make") + env.prependOrSetPath(QDir::toNativeSeparators(QFileInfo(m_makeBinary).absolutePath())); // if qmake is not in PATH make sure the correct libs for inferior are prepended to PATH - if (m_qmakeBinary != "qmake") { - Utils::Environment env = Utils::Environment::systemEnvironment(); + if (m_qmakeBinary != "qmake") env.prependOrSetPath(QDir::toNativeSeparators(QFileInfo(m_qmakeBinary).absolutePath())); - m_env = env.toProcessEnvironment(); - } + m_env = env.toProcessEnvironment(); #else + m_env = QProcessEnvironment::systemEnvironment(); if (m_makeBinary.isEmpty()) m_makeBinary = "make"; #endif @@ -1093,14 +1092,14 @@ void tst_Dumpers::initTestCase() QByteArray cdbextPath = qgetenv("QTC_CDBEXT_PATH"); if (cdbextPath.isEmpty()) cdbextPath = CDBEXT_PATH "\\qtcreatorcdbext64"; - QVERIFY(QFile::exists(QString::fromLatin1(cdbextPath + QByteArray("\\qtcreatorcdbext.dll")))); - env.set(QLatin1String("_NT_DEBUGGER_EXTENSION_PATH"), QString::fromLatin1(cdbextPath)); + QVERIFY(QFile::exists(cdbextPath + "\\qtcreatorcdbext.dll")); + env.set("_NT_DEBUGGER_EXTENSION_PATH", cdbextPath); env.prependOrSetPath(QDir::toNativeSeparators(QFileInfo(m_qmakeBinary).absolutePath())); - m_makeBinary = env.searchInPath(QLatin1String("nmake.exe")).toString(); + m_makeBinary = env.searchInPath("nmake.exe").toString(); m_env = env.toProcessEnvironment(); QProcess cl; - cl.start(env.searchInPath(QLatin1String("cl.exe")).toString(), QStringList()); + cl.start(env.searchInPath("cl.exe").toString(), QStringList()); QVERIFY(cl.waitForFinished()); QString output = cl.readAllStandardError(); int pos = output.indexOf('\n'); @@ -1115,8 +1114,7 @@ void tst_Dumpers::initTestCase() } else if (m_debuggerEngine == LldbEngine) { qDebug() << "Dumper dir : " << DUMPERDIR; QProcess debugger; - QString cmd = m_debuggerBinary + " -v"; - debugger.start(cmd); + debugger.start(m_debuggerBinary, {"-v"}); bool ok = debugger.waitForFinished(2000); QVERIFY(ok); QByteArray output = debugger.readAllStandardOutput(); @@ -1155,7 +1153,7 @@ void tst_Dumpers::init() void tst_Dumpers::cleanup() { if (!t->buildTemp.autoRemove()) { - QFile logger(t->buildPath + QLatin1String("/input.txt")); + QFile logger(t->buildPath + "/input.txt"); logger.open(QIODevice::ReadWrite); logger.write(t->input.toUtf8()); } @@ -1187,22 +1185,20 @@ void tst_Dumpers::dumper() + QByteArray::number(data.neededLldbVersion.max)); } - QString cmd; QByteArray output; QByteArray error; if (data.neededQtVersion.isRestricted) { QProcess qmake; qmake.setWorkingDirectory(t->buildPath); - cmd = m_qmakeBinary; - qmake.start(cmd, QStringList(QLatin1String("--version"))); + qmake.start(m_qmakeBinary, {"--version"}); QVERIFY(qmake.waitForFinished()); output = qmake.readAllStandardOutput(); error = qmake.readAllStandardError(); int pos0 = output.indexOf("Qt version"); if (pos0 == -1) { - qDebug() << "Output: " << output; - qDebug() << "Error: " << error; + qDebug().noquote() << "Output: " << output; + qDebug().noquote() << "Error: " << error; QVERIFY(false); } pos0 += 11; @@ -1225,8 +1221,7 @@ void tst_Dumpers::dumper() if (data.neededGccVersion.isRestricted) { QProcess gcc; gcc.setWorkingDirectory(t->buildPath); - cmd = QLatin1String("gcc"); - gcc.start(cmd, QStringList(QLatin1String("--version"))); + gcc.start("gcc", {"--version"}); QVERIFY(gcc.waitForFinished()); output = gcc.readAllStandardOutput(); error = gcc.readAllStandardError(); @@ -1304,12 +1299,14 @@ void tst_Dumpers::dumper() } proFile.close(); - QFile source(t->buildPath + QLatin1Char('/') + data.mainFile); + QFile source(t->buildPath + '/' + data.mainFile); QVERIFY(source.open(QIODevice::ReadWrite)); QString fullCode = QString() + - "\n\n#if defined(_MSC_VER)" + (data.useQt ? + "\n\n#ifdef _WIN32" + (data.useQt ? "\n#include <qt_windows.h>" : - "\n#define NOMINMAX\n#include <Windows.h>") + + "\n#define NOMINMAX\n#include <windows.h>") + + "\n#endif" + "\n#if defined(_MSC_VER)" "\nvoid qtcDebugBreakFunction() { return; }" "\n#define BREAK qtcDebugBreakFunction();" "\n\nvoid unused(const void *first,...) { (void) first; }" @@ -1389,14 +1386,13 @@ void tst_Dumpers::dumper() QProcess qmake; qmake.setWorkingDirectory(t->buildPath); - cmd = m_qmakeBinary; - //qDebug() << "Starting qmake: " << cmd; + //qDebug() << "Starting qmake: " << m_qmakeBinary; QStringList options; #ifdef Q_OS_MAC if (m_qtVersion && m_qtVersion < 0x050000) options << "-spec" << "unsupported/macx-clang"; #endif - qmake.start(cmd, options); + qmake.start(m_qmakeBinary, options); QVERIFY(qmake.waitForFinished()); output = qmake.readAllStandardOutput(); error = qmake.readAllStandardError(); @@ -1423,6 +1419,7 @@ void tst_Dumpers::dumper() qDebug().noquote() << fullCode; qDebug() << "\n------------------ CODE --------------------"; qDebug().noquote() << "Project file: " << proFile.fileName(); + QCOMPARE(make.exitCode(), 0); } if (data.neededDwarfVersion.isRestricted) { @@ -1451,7 +1448,7 @@ void tst_Dumpers::dumper() QSet<QString> expandedINames; expandedINames.insert("local"); - foreach (const Check &check, data.checks) { + for (const Check &check : Utils::asConst(data.checks)) { QString parent = check.iname; while (true) { parent = parentIName(parent); @@ -1463,7 +1460,7 @@ void tst_Dumpers::dumper() QString expanded; QString expandedq; - foreach (const QString &iname, expandedINames) { + for (const QString &iname : Utils::asConst(expandedINames)) { if (!expanded.isEmpty()) { expanded.append(','); expandedq.append(','); @@ -1512,13 +1509,13 @@ void tst_Dumpers::dumper() cmds += "quit\n"; } else if (m_debuggerEngine == CdbEngine) { - args << QLatin1String("-aqtcreatorcdbext.dll") - << QLatin1String("-G") - << QLatin1String("-xn") - << QLatin1String("0x4000001f") - << QLatin1String("-c") - << QLatin1String("bm doit!qtcDebugBreakFunction;g") - << QLatin1String("debug\\doit.exe"); + args << "-aqtcreatorcdbext.dll" + << "-G" + << "-xn" + << "0x4000001f" + << "-c" + << "bm doit!qtcDebugBreakFunction;g" + << "debug\\doit.exe"; cmds += "!qtcreatorcdbext.script sys.path.insert(1, '" + dumperDir + "')\n" "!qtcreatorcdbext.script from cdbbridge import *\n" "!qtcreatorcdbext.script theDumper = Dumper()\n" @@ -1532,7 +1529,7 @@ void tst_Dumpers::dumper() "'expanded':[" + expandedq + "]})\n" "q\n"; } else if (m_debuggerEngine == LldbEngine) { - QFile fullLldb(t->buildPath + QLatin1String("/lldbcommand.txt")); + QFile fullLldb(t->buildPath + "/lldbcommand.txt"); fullLldb.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ExeOwner|QFile::ReadGroup|QFile::ReadOther); fullLldb.open(QIODevice::WriteOnly); fullLldb.write((exe + ' ' + args.join(' ') + '\n').toUtf8()); @@ -1574,7 +1571,7 @@ void tst_Dumpers::dumper() qDebug() << error; if (keepTemp()) { - QFile logger(t->buildPath + QLatin1String("/output.txt")); + QFile logger(t->buildPath + "/output.txt"); logger.open(QIODevice::ReadWrite); logger.write("=== STDOUT ===\n"); logger.write(output); @@ -1641,7 +1638,7 @@ void tst_Dumpers::dumper() WatchItem local; local.iname = "local"; - foreach (const GdbMi &child, actual.children()) { + for (const GdbMi &child : Utils::asConst(actual.children())) { const QString iname = child["iname"].data(); if (iname == "local.qtversion") context.qtVersion = child["value"].toInt(); @@ -1719,7 +1716,7 @@ void tst_Dumpers::dumper() if (!data.checks.isEmpty()) { qDebug() << "SOME TESTS NOT EXECUTED: "; - foreach (const Check &check, data.checks) { + for (const Check &check : Utils::asConst(data.checks)) { if (check.optionallyPresent) { qDebug() << " OPTIONAL TEST NOT FOUND FOR INAME: " << check.iname << " IGNORED."; } else { @@ -3408,7 +3405,7 @@ void tst_Dumpers::dumper_data() expected1.append(QChar(1)); expected1.append("BBB\""); - QChar oUmlaut = QLatin1Char(char(0xf6)); + QChar oUmlaut = 0xf6; QTest::newRow("QString") << Data("#include <QByteArray>\n" diff --git a/tests/auto/utils/camelhumpmatcher/tst_camelhumpmatcher.cpp b/tests/auto/utils/camelhumpmatcher/tst_camelhumpmatcher.cpp index 6884ee8d7b..d9b5474341 100644 --- a/tests/auto/utils/camelhumpmatcher/tst_camelhumpmatcher.cpp +++ b/tests/auto/utils/camelhumpmatcher/tst_camelhumpmatcher.cpp @@ -68,16 +68,19 @@ void tst_CamelHumpMatcher::camelHumpMatcher_data() QTest::newRow("incorrect-hump") << "lyn" << "VeryLongCamelHump" << -1; QTest::newRow("humps") << "VL" << "VeryLongCamelHump" << 0; QTest::newRow("skipped-humps-upper") << "VH" << "VeryLongCamelHump" << -1; + QTest::newRow("numbers") << "4" << "Test4Fun" << 4; QTest::newRow("question-wildcard") << "Lon?Ca" << "VeryLongCamelHump" << 4; QTest::newRow("unmatched-question-wildcard") << "Long?Ca" << "VeryLongCamelHump" << -1; - QTest::newRow("asterix-wildcard") << "Long*Ca" << "VeryLongCamelHump" << 4; - QTest::newRow("empty-asterix-wildcard") << "Lo*Ca" << "VeryLongCamelHump" << 4; + QTest::newRow("asterisk-wildcard") << "Long*Ca" << "VeryLongCamelHump" << 4; + QTest::newRow("empty-asterisk-wildcard") << "Lo*Ca" << "VeryLongCamelHump" << 4; QTest::newRow("no-partial") << "NCH" << "LongCamelHump" << -1; QTest::newRow("middle-after-number") << "CH" << "Long1CamelHump" << 5; QTest::newRow("middle-after-underscore") << "CH" << "long_camel_hump" << 5; QTest::newRow("middle-after-underscore-uppercase") << "CH" << "LONG_CAMEL_HUMP" << 5; QTest::newRow("middle-continued") << "cahu" << "LongCamelHump" << 4; QTest::newRow("middle-no-hump") << "window" << "mainwindow.cpp" << 4; + QTest::newRow("case-insensitive") << "window" << "MAINWINDOW.cpp" << 4; + QTest::newRow("case-insensitive-2") << "wINDow" << "MainwiNdow.cpp" << 4; } typedef QVector<int> MatchStart; @@ -133,6 +136,8 @@ void tst_CamelHumpMatcher::highlighting_data() << MatchStart{13} << MatchLength{1}; QTest::newRow("humps-continued") << "LoCa" << "VeryLongCamelHump" << MatchStart{4, 8} << MatchLength{2, 2}; + QTest::newRow("numbers") << "4" << "TestJust4Fun" + << MatchStart{8} << MatchLength{1}; QTest::newRow("wildcard-asterisk") << "Lo*Hu" << "VeryLongCamelHump" << MatchStart{4, 13} << MatchLength{2, 2}; QTest::newRow("wildcard-question") << "Lo?g" << "VeryLongCamelHump" diff --git a/tests/auto/utils/stringutils/tst_stringutils.cpp b/tests/auto/utils/stringutils/tst_stringutils.cpp index 6fbdfb4326..8e51c89300 100644 --- a/tests/auto/utils/stringutils/tst_stringutils.cpp +++ b/tests/auto/utils/stringutils/tst_stringutils.cpp @@ -243,6 +243,18 @@ void tst_StringUtils::testParseUsedPortFromNetstatOutput_data() QTest::newRow("Mac6") << "tcp6 0 0 *.631 *.* LISTEN" << 631; QTest::newRow("Mac7") << "udp4 0 0 192.168.79.1.123 *.*" << 123; QTest::newRow("Mac9") << "udp4 0 0 192.168.8.1.123 *.*" << 123; + + // QNX + QTest::newRow("Qnx1") << "Active Internet connections (including servers)" << -1; + QTest::newRow("Qnx2") << "Proto Recv-Q Send-Q Local Address Foreign Address State " << -1; + QTest::newRow("Qnx3") << "tcp 0 0 10.9.7.5.22 10.9.7.4.46592 ESTABLISHED" << 22; + QTest::newRow("Qnx4") << "tcp 0 0 *.8000 *.* LISTEN " << 8000; + QTest::newRow("Qnx5") << "tcp 0 0 *.22 *.* LISTEN " << 22; + QTest::newRow("Qnx6") << "udp 0 0 *.* *.* " << -1; + QTest::newRow("Qnx7") << "udp 0 0 *.* *.* " << -1; + QTest::newRow("Qnx8") << "Active Internet6 connections (including servers)" << -1; + QTest::newRow("Qnx9") << "Proto Recv-Q Send-Q Local Address Foreign Address (state) " << -1; + QTest::newRow("QnxA") << "tcp6 0 0 *.22 *.* LISTEN " << 22; } QTEST_MAIN(tst_StringUtils) diff --git a/tests/manual/proparser/testreader.pro b/tests/manual/proparser/testreader.pro index 022ac67667..a7b7d74cd3 100644 --- a/tests/manual/proparser/testreader.pro +++ b/tests/manual/proparser/testreader.pro @@ -40,6 +40,6 @@ HEADERS += \ RESOURCES += proparser.qrc DEFINES += QMAKE_BUILTIN_PRFS -DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII +DEFINES += QT_NO_CAST_TO_ASCII QT_RESTRICTED_CAST_FROM_ASCII DEFINES += QT_USE_FAST_OPERATOR_PLUS QT_USE_FAST_CONCATENATION DEFINES += PROEVALUATOR_FULL PROEVALUATOR_CUMULATIVE PROEVALUATOR_INIT_PROPS diff --git a/tests/system/suite_debugger/tst_simple_analyze/test.py b/tests/system/suite_debugger/tst_simple_analyze/test.py index d01d5cbc96..5de123db4d 100644 --- a/tests/system/suite_debugger/tst_simple_analyze/test.py +++ b/tests/system/suite_debugger/tst_simple_analyze/test.py @@ -112,7 +112,7 @@ def performTest(workingDir, projectName, targetCount, availableConfigs): test.compare(dumpItems(model, column=colPercent)[0], '100.00 %') # cannot run following test on colShortest (unstable) for i in [colTotal, colMean, colMedian, colLongest]: - for item in dumpItems(model, column=i)[1:5]: + for item in dumpItems(model, column=i)[2:5]: test.verify(item.endswith('ms'), "Verify that '%s' ends with 'ms'" % item) for i in [colTotal, colMean, colMedian, colLongest, colShortest]: for item in dumpItems(model, column=i): diff --git a/tests/unit/unittest/clangcodemodelserver-test.cpp b/tests/unit/unittest/clangcodemodelserver-test.cpp index eeb500215b..b1b4e8dc8a 100644 --- a/tests/unit/unittest/clangcodemodelserver-test.cpp +++ b/tests/unit/unittest/clangcodemodelserver-test.cpp @@ -629,7 +629,7 @@ void ClangCodeModelServer::expectDocumentAnnotationsChangedForFileBWithSpecificH HighlightingTypes types; types.mainHighlightingType = ClangBackEnd::HighlightingType::Function; types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::Declaration); - const HighlightingMarkContainer highlightingMark(1, 6, 8, types); + const HighlightingMarkContainer highlightingMark(1, 6, 8, types, true); EXPECT_CALL(mockClangCodeModelClient, documentAnnotationsChanged( diff --git a/tests/unit/unittest/creator_dependency.pri b/tests/unit/unittest/creator_dependency.pri index b9a5db097c..2a960f323e 100644 --- a/tests/unit/unittest/creator_dependency.pri +++ b/tests/unit/unittest/creator_dependency.pri @@ -16,7 +16,7 @@ include($$PWD/../../../src/plugins/cpptools/cpptoolsunittestfiles.pri) include(cplusplus.pri) !isEmpty(LLVM_INSTALL_DIR) { include($$PWD/../../../src/shared/clang/clang_defines.pri) -include($$PWD/../../../src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri) +include($$PWD/../../../src/tools/clangbackend/source/clangbackendclangipc-source.pri) include($$PWD/../../../src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri) } else { DEFINES += CLANG_VERSION=\\\"3.9.1\\\" |