diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 67292e2e26d..1a646ab4e50 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -2931,8 +2931,8 @@ class DumperBase: % (self.name, self.type.name, self.lbitsize, self.lbitpos, self.dumper.hexencode(self.ldata), addr) - def displayEnum(self, form='%d'): - intval = self.integer() + def displayEnum(self, form='%d', bitsize=None): + intval = self.integer(bitsize) dd = self.type.typeData().enumDisplay if dd is None: return str(intval) @@ -2957,7 +2957,7 @@ class DumperBase: return self.detypedef().pointer() return self.extractInteger(self.dumper.ptrSize() * 8, True) - def integer(self): + def integer(self, bitsize=None): if self.type.code == TypeCodeTypedef: return self.detypedef().integer() elif self.type.code == TypeCodeBitfield: @@ -2966,7 +2966,8 @@ class DumperBase: unsigned = self.type.name == 'unsigned' \ or self.type.name.startswith('unsigned ') \ or self.type.name.find(' unsigned ') != -1 - bitsize = self.type.bitsize() + if bitsize is None: + bitsize = self.type.bitsize() return self.extractInteger(bitsize, unsigned) def floatingPoint(self): diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 2aa107429ef..2901c104010 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -492,15 +492,15 @@ def qdump__QEvent(d, value): with Children(d): # Add a sub-item with the event type. with SubItem(d, '[type]'): - (vtable, privateD, t) = value.split("pp{ushort}") - event_type_name = "QEvent::Type" + (vtable, privateD, t, flags) = value.split("pp{short}{short}") + event_type_name = d.qtNamespace() + "QEvent::Type" type_value = t.cast(event_type_name) - d.putValue(type_value.displayEnum('0x%04x')) + d.putValue(type_value.displayEnum('0x%04x', bitsize=16)) d.putType(event_type_name) d.putNumChild(0) # Show the rest of the class fields as usual. - d.putFields(value, dumpBase=True) + d.putFields(value) def qdump__QKeyEvent(d, value): # QEvent fields @@ -531,9 +531,9 @@ def qdump__QKeyEvent(d, value): #data = d.encodeString(txt) key_txt_utf8 = d.encodeStringUtf8(txt) - k_type_name = "Qt::Key" - k_casted_to_enum_value = k.cast(k_type_name) - k_name = k_casted_to_enum_value.displayEnum() + k_type_name = d.qtNamespace() + "Qt::Key" + k_cast_to_enum_value = k.cast(k_type_name) + k_name = k_cast_to_enum_value.displayEnum(bitsize=32) matches = re.search(r'Key_(\w+)', k_name) if matches: k_name = matches.group(1) @@ -587,8 +587,8 @@ def qdump__QKeyEvent(d, value): with Children(d): # Add a sub-item with the enum name and value. with SubItem(d, '[{}]'.format(k_type_name)): - k_casted_to_enum_value = k.cast(k_type_name) - d.putValue(k_casted_to_enum_value.displayEnum('0x%04x')) + k_cast_to_enum_value = k.cast(k_type_name) + d.putValue(k_cast_to_enum_value.displayEnum('0x%04x', bitsize=32)) d.putType(k_type_name) d.putNumChild(0) @@ -756,7 +756,7 @@ def qdump__QFlags(d, value): i = value.split('{int}')[0] enumType = value.type[0] v = i.cast(enumType.name) - d.putValue(v.displayEnum('0x%04x')) + d.putValue(v.displayEnum('0x%04x', bitsize=32)) d.putNumChild(0) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 5c8f39747d4..5c91901eab5 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -3040,9 +3040,16 @@ void EditorManager::hideEditorStatusBar(const QString &id) QTextCodec *EditorManager::defaultTextCodec() { QSettings *settings = ICore::settings(); - if (QTextCodec *candidate = QTextCodec::codecForName( - settings->value(Constants::SETTINGS_DEFAULTTEXTENCODING).toByteArray())) + const QByteArray codecName = + settings->value(Constants::SETTINGS_DEFAULTTEXTENCODING).toByteArray(); + if (QTextCodec *candidate = QTextCodec::codecForName(codecName)) return candidate; + // Qt5 doesn't return a valid codec when looking up the "System" codec, but will return + // such a codec when asking for the codec for locale and no matching codec is available. + // So check whether such a codec was saved to the settings. + QTextCodec *localeCodec = QTextCodec::codecForLocale(); + if (codecName == localeCodec->name()) + return localeCodec; if (QTextCodec *defaultUTF8 = QTextCodec::codecForName("UTF-8")) return defaultUTF8; return QTextCodec::codecForLocale(); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 2e4b20bf7f1..6594e7d00c6 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -738,7 +738,7 @@ void DebuggerEnginePrivate::setupViews() connect(&m_continueAction, &QAction::triggered, m_engine, &DebuggerEngine::handleExecContinue); - m_exitAction.setIcon(Icons::DEBUG_EXIT_SMALL.icon()); + m_exitAction.setIcon(Icons::DEBUG_EXIT_SMALL_TOOLBAR.icon()); connect(&m_exitAction, &QAction::triggered, m_engine, &DebuggerEngine::requestRunControlStop); diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp index fb0de4a3293..a3bad8656f0 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp @@ -354,6 +354,7 @@ void JsonWizard::openFiles(const JsonWizard::GeneratorFiles &files) } break; } + result.project()->setNeedsInitialExpansion(true); openedSomething = true; } if (file.attributes() & Core::GeneratedFile::OpenEditorAttribute) { diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 64c41031557..2225b026d18 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -160,6 +160,7 @@ public: Core::Id m_id; bool m_isParsing = false; bool m_hasParsingData = false; + bool m_needsInitialExpansion = false; std::unique_ptr m_document; std::unique_ptr m_rootProjectNode; std::unique_ptr m_containerNode; @@ -306,6 +307,16 @@ void Project::setActiveTarget(Target *target) } } +bool Project::needsInitialExpansion() const +{ + return d->m_needsInitialExpansion; +} + +void Project::setNeedsInitialExpansion(bool needsExpansion) +{ + d->m_needsInitialExpansion = needsExpansion; +} + Target *Project::target(Core::Id id) const { return Utils::findOrDefault(d->m_targets, Utils::equal(&Target::id, id)); diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 55ddb8de8e5..563328bf07b 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -191,6 +191,9 @@ public: }, recv, this); } + bool needsInitialExpansion() const; + void setNeedsInitialExpansion(bool needsInitialExpansion); + signals: void displayNameChanged(); void fileListChanged(); diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index c009925c97e..ab09068e3b9 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -239,6 +239,10 @@ void FlatModel::addOrRebuildProjectModel(Project *project) if (m_trimEmptyDirectories) trimEmptyDirectories(container); } + + if (project->needsInitialExpansion()) + m_toExpand.insert(expandDataForNode(container->m_node)); + if (container->childCount() == 0) { auto projectFileNode = std::make_unique(project->projectFilePath(), FileType::Project, false); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index b9d50970bac..7a4ed3efb81 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -1173,6 +1173,7 @@ void QmakeProject::collectLibraryData(const QmakeProFile *file, DeploymentData & const QStringList config = file->variableValue(Variable::Config); const bool isStatic = config.contains(QLatin1String("static")); const bool isPlugin = config.contains(QLatin1String("plugin")); + const bool nameIsVersioned = !isPlugin && !config.contains("unversioned_libname"); switch (toolchain->targetAbi().os()) { case Abi::WindowsOS: { QString targetVersionExt = file->singleVariableValue(Variable::TargetVersionExt); @@ -1197,7 +1198,7 @@ void QmakeProject::collectLibraryData(const QmakeProFile *file, DeploymentData & if (!(isPlugin && config.contains(QLatin1String("no_plugin_name_prefix")))) targetFileName.prepend(QLatin1String("lib")); - if (!isPlugin) { + if (nameIsVersioned) { targetFileName += QLatin1Char('.'); const QString version = file->singleVariableValue(Variable::Version); QString majorVersion = version.left(version.indexOf(QLatin1Char('.'))); @@ -1225,7 +1226,7 @@ void QmakeProject::collectLibraryData(const QmakeProFile *file, DeploymentData & } else { targetFileName += QLatin1String("so"); deploymentData.addFile(destDirFor(ti).toString() + '/' + targetFileName, targetPath); - if (!isPlugin) { + if (nameIsVersioned) { QString version = file->singleVariableValue(Variable::Version); if (version.isEmpty()) version = QLatin1String("1.0.0"); diff --git a/tests/system/README b/tests/system/README index ff17e5190e0..57816f235bf 100644 --- a/tests/system/README +++ b/tests/system/README @@ -63,8 +63,9 @@ Fifth - you'll have to make sure that some needed tools are available (no matter Normally it should be okay to just install them as usual and add their executables' path(s) to the PATH variable. Sixth - Qt Creator must be built on a Qt without Qt WebEngine or Qt WebKit. Its ClangCodeModel -plugin should be built. How to do so, see QTCREATOR_REPO/README.md. Without the plugin, the tests -for ClangCodeModel will be skipped but will not cause failures. +plugin should be linked to LLVM/Clang 7.0.0 or later. How to do so, see QTCREATOR_REPO/README.md. +With a lower version, the tests for the ClangCodeModel might fail. Without the plugin, the tests for +the ClangCodeModel will be skipped but will not cause failures. On macOS make sure you are using the correct keyboard layout to avoid problems when using keyboard interaction. Tested and known to be working would be 'U.S. International - PC', while pure 'U.S.' had problems. diff --git a/tests/system/suite_general/tst_default_settings/test.py b/tests/system/suite_general/tst_default_settings/test.py index 92f5898e203..a24307dd4a8 100644 --- a/tests/system/suite_general/tst_default_settings/test.py +++ b/tests/system/suite_general/tst_default_settings/test.py @@ -29,9 +29,10 @@ currentSelectedTreeItem = None warningOrError = re.compile('

((Error|Warning).*?)

') def main(): + global appContext emptySettings = tempDir() __createMinimumIni__(emptySettings) - startQC(['-settingspath', '"%s"' % emptySettings], False) + appContext = startQC(['-settingspath', '"%s"' % emptySettings], False) if not startedWithoutPluginError(): return invokeMenuItem("Tools", "Options...") @@ -172,6 +173,37 @@ def __kitFunc__(it, foundQt, foundCompNames): details = details.replace("", "").replace("", "") test.warning("Detected error and/or warning: %s" % details) +def __extendExpectedCompilersWithInternalClang__(expected): + global appContext + # QC ships a clang itself + regex = '^(.*(qtcreator(.exe)?|Qt Creator))( .*)?$' # QC with optional arguments + qcPath = re.match(regex, appContext.commandLine) + if qcPath is None: + test.warning("Regular expression failed.") + else: + qcPath = qcPath.group(1) + if platform.system() == 'Darwin': + internalClang = os.path.join(qcPath, '..', '..', 'Resources') + elif platform.system() in ('Windows', 'Microsoft'): + internalClang = os.path.join(qcPath, '..') + else: + internalClang = os.path.join(qcPath, '..', '..', 'libexec', 'qtcreator') + internalClang = os.path.join(internalClang, 'clang', 'bin', 'clang') + if platform.system() in ('Microsoft', 'Windows'): + internalClang += '-cl.exe' + internalClang = os.path.abspath(internalClang) + if os.path.exists(internalClang): + if platform.system() in ('Microsoft', 'Windows'): + # just add a fuzzy comparable name - everything else is not worth the effort here + expected.append({'^Default LLVM \d{2} bit based on MSVC\d{4}$':''}) + else: + expected.append(internalClang) + else: + test.fail("QC package seems to be faulty - missing internal provided clang.\nIf this " + "is not a package, but a self-compiled QC, just copy the clang executable " + "located inside the LLVM_INSTALL_DIR/bin (used while building) to the " + "expected path.", "Expected '%s'" % internalClang) + def __getExpectedCompilers__(): # TODO: enhance this to distinguish between C and C++ compilers expected = [] @@ -179,7 +211,8 @@ def __getExpectedCompilers__(): expected.extend(__getWinCompilers__()) compilers = ["g++", "gcc"] if platform.system() in ('Linux', 'Darwin'): - compilers.extend(["clang++", "clang"]) + compilers.extend(["clang++", "clang", "afl-clang"]) + compilers.extend(findAllFilesInPATH("clang-[0-9].[0-9]")) compilers.extend(findAllFilesInPATH("*g++*")) compilers.extend(findAllFilesInPATH("*gcc*")) if platform.system() == 'Darwin': @@ -187,6 +220,9 @@ def __getExpectedCompilers__(): xcodeClang = getOutputFromCmdline(["xcrun", "--find", compilerExe]).strip("\n") if xcodeClang and os.path.exists(xcodeClang) and xcodeClang not in expected: expected.append(xcodeClang) + + __extendExpectedCompilersWithInternalClang__(expected) + for compiler in compilers: compilerPath = which(compiler) if compilerPath: @@ -275,6 +311,13 @@ def __compareCompilers__(foundCompilers, expectedCompilers): if isinstance(currentExp, (str, unicode)): continue key = currentExp.keys()[0] + # special case for (fuzzy) regex comparison on Windows (internal LLVM) + if isWin and key.startswith('^') and key.endswith('$'): + if re.match(key, currentFound.keys()[0], flags): + test.verify(os.path.exists(currentFound.values()[0].rsplit(" ", 1)[0]), + "Verifying whether shipped clang got set up.") + foundExp = True + break # the regex .*? is used for the different possible version strings of the WinSDK # if it's present a regex will be validated otherwise simple string comparison if (((".*?" in key and re.match(key, currentFound.keys()[0], flags)) diff --git a/tests/system/suite_tools/tst_git_clone/test.py b/tests/system/suite_tools/tst_git_clone/test.py index 95ea891c4d8..dbafe776908 100644 --- a/tests/system/suite_tools/tst_git_clone/test.py +++ b/tests/system/suite_tools/tst_git_clone/test.py @@ -65,11 +65,10 @@ def verifyVersionControlView(targetDir, canceled): vcsLog = str(waitForObject("{type='Core::OutputWindow' unnamed='1' visible='1' " "window=':Qt Creator_Core::Internal::MainWindow'}").plainText) test.log("Clone log is: %s" % vcsLog) - if not JIRA.isBugStillOpen(20813): - test.verify("Running in " + targetDir + ":" in vcsLog, - "Searching for target directory in clone log") - test.verify(" ".join(["clone", "--progress", cloneUrl, cloneDir]) in vcsLog, - "Searching for git parameters in clone log") + test.verify("Running in " + targetDir + ":" in vcsLog, + "Searching for target directory in clone log") + test.verify(" ".join(["clone", "--progress", cloneUrl, cloneDir]) in vcsLog, + "Searching for git parameters in clone log") test.verify(canceled == (" terminated abnormally" in vcsLog), "Searching for result in clone log") clickButton(waitForObject(":*Qt Creator.Clear_QToolButton"))