Merge "Merge remote-tracking branch 'origin/4.8'"

This commit is contained in:
Eike Ziller
2018-11-29 12:36:57 +00:00
committed by The Qt Project
63 changed files with 638 additions and 287 deletions

View File

@@ -53,7 +53,7 @@ BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false BreakStringLiterals: true
ColumnLimit: 100 ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false CompactNamespaces: false

View File

@@ -103,6 +103,14 @@
\endlist \endlist
\note When using the command line tools instead of Android Studio,
it is recommended to create an empty folder and extract the
downloaded archive into this folder.
The sdkmanager will install downloaded packages next to the
\c tools folder that contains all command line tools.
You must specify the path to the folder where you extracted the
files as Android SDK location inside the Android settings.
\endlist \endlist
\section1 Setting Up the Development Environment \section1 Setting Up the Development Environment

View File

@@ -167,6 +167,9 @@ function toolingParameters(llvmConfig)
"-Wcovered-switch-default", "-Wcovered-switch-default",
"-Wnon-virtual-dtor", "-Wnon-virtual-dtor",
"-Woverloaded-virtual", "-Woverloaded-virtual",
"-Wmissing-field-initializers",
"-Wno-unknown-warning",
"-Wno-unused-command-line-argument",
"-fPIC", "-fPIC",
"-pedantic", "-pedantic",
"-Wstring-conversion", "-Wstring-conversion",

View File

@@ -4,16 +4,16 @@ import qbs.FileInfo
import "qtc.js" as HelperFunctions import "qtc.js" as HelperFunctions
Module { Module {
property string qtcreator_display_version: '4.8.0-rc1' property string qtcreator_display_version: '4.8.0'
property string ide_version_major: '4' property string ide_version_major: '4'
property string ide_version_minor: '7' property string ide_version_minor: '8'
property string ide_version_release: '84' property string ide_version_release: '0'
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.'
+ ide_version_release + ide_version_release
property string ide_compat_version_major: '4' property string ide_compat_version_major: '4'
property string ide_compat_version_minor: '7' property string ide_compat_version_minor: '8'
property string ide_compat_version_release: '84' property string ide_compat_version_release: '0'
property string qtcreator_compat_version: ide_compat_version_major + '.' property string qtcreator_compat_version: ide_compat_version_major + '.'
+ ide_compat_version_minor + '.' + ide_compat_version_release + ide_compat_version_minor + '.' + ide_compat_version_release

View File

@@ -1,10 +1,10 @@
!isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included") !isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included")
QTCREATOR_PRI_INCLUDED = 1 QTCREATOR_PRI_INCLUDED = 1
QTCREATOR_VERSION = 4.7.84 QTCREATOR_VERSION = 4.8.0
QTCREATOR_COMPAT_VERSION = 4.7.84 QTCREATOR_COMPAT_VERSION = 4.8.0
VERSION = $$QTCREATOR_VERSION VERSION = $$QTCREATOR_VERSION
QTCREATOR_DISPLAY_VERSION = 4.8.0-rc1 QTCREATOR_DISPLAY_VERSION = 4.8.0
QTCREATOR_COPYRIGHT_YEAR = 2018 QTCREATOR_COPYRIGHT_YEAR = 2018
BINARY_ARTIFACTS_BRANCH = 4.8 BINARY_ARTIFACTS_BRANCH = 4.8

View File

@@ -203,8 +203,6 @@ public:
virtual bool check(bool enable = true); virtual bool check(bool enable = true);
}; };
bool Derived2::
// performance-unnecessary-value-param // performance-unnecessary-value-param
void use(Base b) void use(Base b)
{ {

View File

@@ -1083,6 +1083,7 @@ class Dumper(DumperBase):
addr = frame.GetPCAddress().GetLoadAddress(self.target) addr = frame.GetPCAddress().GetLoadAddress(self.target)
functionName = frame.GetFunctionName() functionName = frame.GetFunctionName()
module = frame.GetModule()
if isNativeMixed and functionName == '::qt_qmlDebugMessageAvailable()': if isNativeMixed and functionName == '::qt_qmlDebugMessageAvailable()':
interpreterStack = self.extractInterpreterStack() interpreterStack = self.extractInterpreterStack()
@@ -1102,6 +1103,7 @@ class Dumper(DumperBase):
result += ',address="0x%x"' % addr result += ',address="0x%x"' % addr
result += ',function="%s"' % functionName result += ',function="%s"' % functionName
result += ',line="%d"' % lineNumber result += ',line="%d"' % lineNumber
result += ',module="%s"' % module
result += ',file="%s"},' % fileName result += ',file="%s"},' % fileName
result += ']' result += ']'
result += ',hasmore="%d"' % isLimited result += ',hasmore="%d"' % isLimited
@@ -1652,7 +1654,7 @@ class Dumper(DumperBase):
def selectThread(self, args): def selectThread(self, args):
self.reportToken(args) self.reportToken(args)
self.process.SetSelectedThreadByID(args['id']) self.process.SetSelectedThreadByID(int(args['id']))
self.reportResult('', args) self.reportResult('', args)
def fetchFullBacktrace(self, _ = None): def fetchFullBacktrace(self, _ = None):

View File

@@ -130,7 +130,7 @@ TreeViewArrowColorSelected=text
OutputPanes_DebugTextColor=text OutputPanes_DebugTextColor=text
OutputPanes_ErrorMessageTextColor=ffff6c6c OutputPanes_ErrorMessageTextColor=ffff6c6c
OutputPanes_MessageOutput=ff008787 OutputPanes_MessageOutput=ff008787
OutputPanes_NormalMessageTextColor=text OutputPanes_NormalMessageTextColor=ff008787
OutputPanes_StdErrTextColor=ffff6666 OutputPanes_StdErrTextColor=ffff6666
OutputPanes_StdOutTextColor=text OutputPanes_StdOutTextColor=text
OutputPanes_WarningMessageTextColor=fff3c300 OutputPanes_WarningMessageTextColor=fff3c300

View File

@@ -190,7 +190,7 @@ TreeViewArrowColorSelected=text
OutputPanes_DebugTextColor=text OutputPanes_DebugTextColor=text
OutputPanes_ErrorMessageTextColor=ffff6c6c OutputPanes_ErrorMessageTextColor=ffff6c6c
OutputPanes_MessageOutput=ff008787 OutputPanes_MessageOutput=ff008787
OutputPanes_NormalMessageTextColor=text OutputPanes_NormalMessageTextColor=ff008787
OutputPanes_StdErrTextColor=ffff6666 OutputPanes_StdErrTextColor=ffff6666
OutputPanes_StdOutTextColor=text OutputPanes_StdOutTextColor=text
OutputPanes_WarningMessageTextColor=fff3c300 OutputPanes_WarningMessageTextColor=fff3c300

View File

@@ -134,7 +134,7 @@ TreeViewArrowColorSelected=text
OutputPanes_DebugTextColor=text OutputPanes_DebugTextColor=text
OutputPanes_ErrorMessageTextColor=ffff6c6c OutputPanes_ErrorMessageTextColor=ffff6c6c
OutputPanes_MessageOutput=ff008787 OutputPanes_MessageOutput=ff008787
OutputPanes_NormalMessageTextColor=text OutputPanes_NormalMessageTextColor=ff008787
OutputPanes_StdErrTextColor=ffff6666 OutputPanes_StdErrTextColor=ffff6666
OutputPanes_StdOutTextColor=text OutputPanes_StdOutTextColor=text
OutputPanes_WarningMessageTextColor=fff3c300 OutputPanes_WarningMessageTextColor=fff3c300

View File

@@ -13790,25 +13790,25 @@ Soll es noch einmal versucht werden?</translation>
<source>Record Macro</source> <source>Record Macro</source>
<translation>Makroaufnahme</translation> <translation>Makroaufnahme</translation>
</message> </message>
<message>
<source>Ctrl+(</source>
<translation>Ctrl+(</translation>
</message>
<message>
<source>Alt+(</source>
<translation>Alt+(</translation>
</message>
<message> <message>
<source>Stop Recording Macro</source> <source>Stop Recording Macro</source>
<translation>Makroaufnahme anhalten</translation> <translation>Makroaufnahme anhalten</translation>
</message> </message>
<message> <message>
<source>Ctrl+)</source> <source>Ctrl+[</source>
<translation>Ctrl+)</translation> <translation>Ctrl+[</translation>
</message> </message>
<message> <message>
<source>Alt+)</source> <source>Alt+[</source>
<translation>Alt+)</translation> <translation>Alt+[</translation>
</message>
<message>
<source>Ctrl+]</source>
<translation>Ctrl+]</translation>
</message>
<message>
<source>Alt+]</source>
<translation>Alt+]</translation>
</message> </message>
<message> <message>
<source>Play Last Macro</source> <source>Play Last Macro</source>
@@ -20476,20 +20476,6 @@ should a repository require SSH-authentication (see documentation on SSH and the
<source>Missing Android SDK packages</source> <source>Missing Android SDK packages</source>
<translation>Fehlende Android-SDK-Pakete</translation> <translation>Fehlende Android-SDK-Pakete</translation>
</message> </message>
<message>
<source>Cannot create kits for all architectures.</source>
<translation>Kits können nicht für alle Architekturen erstellt werden.</translation>
</message>
<message>
<source>Qt versions are missing for the following architectures:
%1
To add the Qt version, select Options &gt; Build &amp; Run &gt; Qt Versions.</source>
<translation>Es fehlen Qt-Versionen für die folgenden Architekturen:
%1
Um die Qt-Versionen hinzuzufügen, benutzen Sie Einstellungen &gt; Erstellung und Ausführung &gt; Qt Versionen.</translation>
</message>
<message> <message>
<source>(SDK Version: %1, NDK Version: %2)</source> <source>(SDK Version: %1, NDK Version: %2)</source>
<translation>(SDK-Version: %1, NDK-Version: %2)</translation> <translation>(SDK-Version: %1, NDK-Version: %2)</translation>
@@ -20498,15 +20484,8 @@ Um die Qt-Versionen hinzuzufügen, benutzen Sie Einstellungen &gt; Erstellung un
<context> <context>
<name>Android::Internal::AndroidToolChainFactory</name> <name>Android::Internal::AndroidToolChainFactory</name>
<message> <message>
<source>Android GCC</source> <source>Android Clang</source>
<translation>Android GCC</translation> <translation>Android Clang</translation>
</message>
</context>
<context>
<name>Android::Internal::AndroidToolChainConfigWidget</name>
<message>
<source>NDK Root:</source>
<translation>NDK Root:</translation>
</message> </message>
</context> </context>
<context> <context>
@@ -30364,8 +30343,8 @@ Der vom Kit mindestens benötigte API-Level ist %1.</translation>
<translation>Android-Debugger für %1</translation> <translation>Android-Debugger für %1</translation>
</message> </message>
<message> <message>
<source>Android for %1 (GCC %2, %3)</source> <source>Android for %1 (Clang %2)</source>
<translation>Android für %1 (GCC %2, %3)</translation> <translation>Android für %1 (Clang %2)</translation>
</message> </message>
</context> </context>
<context> <context>
@@ -46059,6 +46038,10 @@ Die Dateien aus dem Quellverzeichnis des Android-Pakets werden in das Verzeichni
<source>Unexpectedly finished. Restarting in %1 seconds.</source> <source>Unexpectedly finished. Restarting in %1 seconds.</source>
<translation>Unerwartet beendet. Neustart in %1 Sekunden.</translation> <translation>Unerwartet beendet. Neustart in %1 Sekunden.</translation>
</message> </message>
<message>
<source>Unexpectedly finished.</source>
<translation>Unerwartet beendet.</translation>
</message>
</context> </context>
<context> <context>
<name>LanguageClient::BaseSettingsWidget</name> <name>LanguageClient::BaseSettingsWidget</name>

View File

@@ -455,7 +455,11 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
// executable cannot be found in the path. Do not start the // executable cannot be found in the path. Do not start the
// event loop in that case. // event loop in that case.
d->m_binary = binary; d->m_binary = binary;
d->m_process.start(binary, args, writeData.isEmpty() ? QIODevice::ReadOnly : QIODevice::ReadWrite); // using QProcess::start() and passing program, args and OpenMode results in a different
// quoting of arguments than using QProcess::setArguments() beforehand and calling start()
// only with the OpenMode
d->m_process.setProgram(binary);
d->m_process.setArguments(args);
connect(&d->m_process, &QProcess::started, this, [this, writeData] { connect(&d->m_process, &QProcess::started, this, [this, writeData] {
if (!writeData.isEmpty()) { if (!writeData.isEmpty()) {
int pos = 0; int pos = 0;
@@ -469,6 +473,8 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
} }
d->m_process.closeWriteChannel(); d->m_process.closeWriteChannel();
}); });
d->m_process.start(writeData.isEmpty() ? QIODevice::ReadOnly : QIODevice::ReadWrite);
if (!d->m_startFailure) { if (!d->m_startFailure) {
d->m_timer.start(); d->m_timer.start();
if (isGuiThread()) if (isGuiThread())

View File

@@ -43,6 +43,8 @@
#include <QPaintEvent> #include <QPaintEvent>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <memory>
namespace Utils { namespace Utils {
namespace Internal { namespace Internal {

View File

@@ -364,7 +364,7 @@ void AndroidManager::setDeviceApiLevel(ProjectExplorer::Target *target, int leve
QPair<int, int> AndroidManager::apiLevelRange() QPair<int, int> AndroidManager::apiLevelRange()
{ {
return qMakePair(16, 27); return qMakePair(16, 28);
} }
QString AndroidManager::androidNameForApiLevel(int x) QString AndroidManager::androidNameForApiLevel(int x)
@@ -418,6 +418,8 @@ QString AndroidManager::androidNameForApiLevel(int x)
return QLatin1String("Android 8.0"); return QLatin1String("Android 8.0");
case 27: case 27:
return QLatin1String("Android 8.1"); return QLatin1String("Android 8.1");
case 28:
return QLatin1String("Android 9");
default: default:
return tr("Unknown Android version. API Level: %1").arg(QString::number(x)); return tr("Unknown Android version. API Level: %1").arg(QString::number(x));
} }

View File

@@ -252,8 +252,9 @@ bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, con
if (!f.open(QIODevice::ReadOnly)) if (!f.open(QIODevice::ReadOnly))
return false; return false;
runAdb({"shell", "run-as", m_packageName, "rm", to}); runAdb({"shell", "run-as", m_packageName, "rm", to});
auto res = runAdb({"shell", "run-as", m_packageName, "sh", "-c", QString("'cat > %1'").arg(to)}, const QByteArray data = f.readAll();
nullptr, f.readAll()); const bool res = runAdb({"shell", "run-as", m_packageName, QString("sh -c 'base64 -d > %1'").arg(to)},
nullptr, data.toBase64());
if (!res) if (!res)
return false; return false;
return runAdb({"shell", "run-as", m_packageName, "chmod", flags, to}); return runAdb({"shell", "run-as", m_packageName, "chmod", flags, to});

View File

@@ -261,6 +261,7 @@ public:
SdkToolsMarker = 0x100, SdkToolsMarker = 0x100,
PlatformToolsMarker = 0x200, PlatformToolsMarker = 0x200,
EmulatorToolsMarker = 0x400, EmulatorToolsMarker = 0x400,
ExtrasMarker = 0x800,
SectionMarkers = InstalledPackagesMarker | AvailablePackagesMarkers | AvailableUpdatesMarker SectionMarkers = InstalledPackagesMarker | AvailablePackagesMarkers | AvailableUpdatesMarker
}; };
@@ -280,6 +281,7 @@ private:
SdkTools *parseSdkToolsPackage(const QStringList &data) const; SdkTools *parseSdkToolsPackage(const QStringList &data) const;
PlatformTools *parsePlatformToolsPackage(const QStringList &data) const; PlatformTools *parsePlatformToolsPackage(const QStringList &data) const;
EmulatorTools *parseEmulatorToolsPackage(const QStringList &data) const; EmulatorTools *parseEmulatorToolsPackage(const QStringList &data) const;
ExtraTools *parseExtraToolsPackage(const QStringList &data) const;
MarkerTag parseMarkers(const QString &line); MarkerTag parseMarkers(const QString &line);
MarkerTag m_currentSection = MarkerTag::None; MarkerTag m_currentSection = MarkerTag::None;
@@ -295,7 +297,8 @@ const std::map<SdkManagerOutputParser::MarkerTag, const char *> markerTags {
{SdkManagerOutputParser::MarkerTag::BuildToolsMarker, "build-tools"}, {SdkManagerOutputParser::MarkerTag::BuildToolsMarker, "build-tools"},
{SdkManagerOutputParser::MarkerTag::SdkToolsMarker, "tools"}, {SdkManagerOutputParser::MarkerTag::SdkToolsMarker, "tools"},
{SdkManagerOutputParser::MarkerTag::PlatformToolsMarker, "platform-tools"}, {SdkManagerOutputParser::MarkerTag::PlatformToolsMarker, "platform-tools"},
{SdkManagerOutputParser::MarkerTag::EmulatorToolsMarker, "emulator"} {SdkManagerOutputParser::MarkerTag::EmulatorToolsMarker, "emulator"},
{SdkManagerOutputParser::MarkerTag::ExtrasMarker, "extras"}
}; };
AndroidSdkManager::AndroidSdkManager(const AndroidConfig &config, QObject *parent): AndroidSdkManager::AndroidSdkManager(const AndroidConfig &config, QObject *parent):
@@ -562,6 +565,10 @@ void SdkManagerOutputParser::parsePackageData(MarkerTag packageMarker, const QSt
} }
break; break;
case MarkerTag::ExtrasMarker:
createPackage(&SdkManagerOutputParser::parseExtraToolsPackage);
break;
default: default:
qCDebug(sdkManagerLog) << "Unhandled package: " << markerTags.at(packageMarker); qCDebug(sdkManagerLog) << "Unhandled package: " << markerTags.at(packageMarker);
break; break;
@@ -726,6 +733,22 @@ EmulatorTools *SdkManagerOutputParser::parseEmulatorToolsPackage(const QStringLi
return emulatorTools; return emulatorTools;
} }
ExtraTools *SdkManagerOutputParser::parseExtraToolsPackage(const QStringList &data) const
{
ExtraTools *extraTools = nullptr;
GenericPackageData packageData;
if (parseAbstractData(packageData, data, 1, "Extras")) {
extraTools = new ExtraTools(packageData.revision, data.at(0));
extraTools->setDescriptionText(packageData.description);
extraTools->setDisplayText(packageData.description);
extraTools->setInstalledLocation(packageData.installedLocation);
} else {
qCDebug(sdkManagerLog) << "Extra-tools: Parsing failed. Minimum required data "
"unavailable:" << data;
}
return extraTools;
}
SdkManagerOutputParser::MarkerTag SdkManagerOutputParser::parseMarkers(const QString &line) SdkManagerOutputParser::MarkerTag SdkManagerOutputParser::parseMarkers(const QString &line)
{ {
if (line.isEmpty()) if (line.isEmpty())

View File

@@ -269,4 +269,19 @@ AndroidSdkPackage::PackageType EmulatorTools::type() const
return AndroidSdkPackage::EmulatorToolsPackage; return AndroidSdkPackage::EmulatorToolsPackage;
} }
ExtraTools::ExtraTools(QVersionNumber revision, QString sdkStylePathStr, QObject *parent) :
AndroidSdkPackage(revision, sdkStylePathStr, parent)
{
}
bool ExtraTools::isValid() const
{
return installedLocation().exists();
}
AndroidSdkPackage::PackageType ExtraTools::type() const
{
return AndroidSdkPackage::ExtraToolsPackage;
}
} // namespace Android } // namespace Android

View File

@@ -53,8 +53,9 @@ public:
SdkPlatformPackage = 1 << 4, SdkPlatformPackage = 1 << 4,
SystemImagePackage = 1 << 5, SystemImagePackage = 1 << 5,
EmulatorToolsPackage = 1 << 6, EmulatorToolsPackage = 1 << 6,
ExtraToolsPackage = 1 << 7,
AnyValidType = SdkToolsPackage | BuildToolsPackage | PlatformToolsPackage | AnyValidType = SdkToolsPackage | BuildToolsPackage | PlatformToolsPackage |
SdkPlatformPackage | SystemImagePackage | EmulatorToolsPackage SdkPlatformPackage | SystemImagePackage | EmulatorToolsPackage | ExtraToolsPackage
}; };
enum PackageState { enum PackageState {
@@ -191,6 +192,16 @@ public:
bool isValid() const override; bool isValid() const override;
PackageType type() const override; PackageType type() const override;
}; };
class ExtraTools : public AndroidSdkPackage
{
public:
ExtraTools(QVersionNumber revision, QString sdkStylePathStr, QObject *parent = nullptr);
// AndroidSdkPackage Overrides
bool isValid() const override;
PackageType type() const override;
};
} // namespace Android } // namespace Android

View File

@@ -73,7 +73,6 @@ public:
static void clearChoiceCache(); static void clearChoiceCache();
private: private:
bool checkLicense();
void initializeMenuEntries(); void initializeMenuEntries();
void onRunAllTriggered(); void onRunAllTriggered();
void onRunSelectedTriggered(); void onRunSelectedTriggered();

View File

@@ -157,6 +157,7 @@ void ClangCompletionContextAnalyzer::handleFunctionCall(int afterOperatorPositio
setActionAndClangPosition(CompleteSlot, afterOperatorPosition); setActionAndClangPosition(CompleteSlot, afterOperatorPosition);
} else if (m_interface->position() != afterOperatorPosition) { } else if (m_interface->position() != afterOperatorPosition) {
// No function completion if cursor is not after '(' or ',' // No function completion if cursor is not after '(' or ','
m_addSnippets = true;
m_positionForProposal = afterOperatorPosition; m_positionForProposal = afterOperatorPosition;
setActionAndClangPosition(PassThroughToLibClang, afterOperatorPosition); setActionAndClangPosition(PassThroughToLibClang, afterOperatorPosition);
} else { } else {

View File

@@ -13,7 +13,9 @@ win32 {
LIBS += $$CLANGFORMAT_LIBS LIBS += $$CLANGFORMAT_LIBS
INCLUDEPATH += $$LLVM_INCLUDEPATH INCLUDEPATH += $$LLVM_INCLUDEPATH
QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS QMAKE_CXXFLAGS_WARN_ON *= $$LLVM_CXXFLAGS_WARNINGS
QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS
unix:!macos:QMAKE_LFLAGS += -Wl,--exclude-libs,ALL
SOURCES = \ SOURCES = \
clangformatconfigwidget.cpp \ clangformatconfigwidget.cpp \

View File

@@ -17,6 +17,7 @@ QtcPlugin {
condition: libclang.present condition: libclang.present
&& (!qbs.targetOS.contains("windows") || libclang.llvmBuildModeMatches) && (!qbs.targetOS.contains("windows") || libclang.llvmBuildModeMatches)
cpp.cxxFlags: base.concat(libclang.llvmToolingCxxFlags)
cpp.defines: base.concat("CLANGPCHMANAGER_LIB") cpp.defines: base.concat("CLANGPCHMANAGER_LIB")
cpp.includePaths: base.concat(libclang.llvmIncludeDir) cpp.includePaths: base.concat(libclang.llvmIncludeDir)
cpp.libraryPaths: base.concat(libclang.llvmLibDir) cpp.libraryPaths: base.concat(libclang.llvmLibDir)

View File

@@ -69,6 +69,13 @@ void adjustFormatStyleForLineBreak(format::FormatStyle &style)
style.SortUsingDeclarations = false; style.SortUsingDeclarations = false;
} }
StringRef clearExtraNewline(StringRef text)
{
while (text.startswith("\n\n"))
text = text.drop_front();
return text;
}
Replacements filteredReplacements(const Replacements &replacements, Replacements filteredReplacements(const Replacements &replacements,
int offset, int offset,
int extraOffsetToAdd, int extraOffsetToAdd,
@@ -83,10 +90,13 @@ Replacements filteredReplacements(const Replacements &replacements,
if (replacementOffset + 1 >= offset) if (replacementOffset + 1 >= offset)
replacementOffset += extraOffsetToAdd; replacementOffset += extraOffsetToAdd;
StringRef text = onlyIndention ? clearExtraNewline(replacement.getReplacementText())
: replacement.getReplacementText();
Error error = filtered.add(Replacement(replacement.getFilePath(), Error error = filtered.add(Replacement(replacement.getFilePath(),
static_cast<unsigned int>(replacementOffset), static_cast<unsigned int>(replacementOffset),
replacement.getLength(), replacement.getLength(),
replacement.getReplacementText())); text));
// Throws if error is not checked. // Throws if error is not checked.
if (error) if (error)
break; break;
@@ -123,6 +133,18 @@ void trimFirstNonEmptyBlock(const QTextBlock &currentBlock)
cursor.endEditBlock(); cursor.endEditBlock();
} }
void trimCurrentBlock(const QTextBlock &currentBlock)
{
if (currentBlock.text().trimmed().isEmpty()) {
// Clear the block containing only spaces
QTextCursor cursor(currentBlock);
cursor.beginEditBlock();
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
cursor.endEditBlock();
}
}
// Returns the total langth of previous lines with pure whitespace. // Returns the total langth of previous lines with pure whitespace.
int previousEmptyLinesLength(const QTextBlock &currentBlock) int previousEmptyLinesLength(const QTextBlock &currentBlock)
{ {
@@ -335,10 +357,19 @@ void ClangFormatIndenter::indent(QTextDocument *doc,
bool /*autoTriggered*/) bool /*autoTriggered*/)
{ {
if (cursor.hasSelection()) { if (cursor.hasSelection()) {
QTextBlock currentBlock = doc->findBlock(cursor.selectionStart()); // Calling currentBlock.next() might be unsafe because we change the document.
while (currentBlock.isValid() && currentBlock.position() < cursor.selectionEnd()) { // Let's operate with block numbers instead.
const int startNumber = doc->findBlock(cursor.selectionStart()).blockNumber();
const int endNumber = doc->findBlock(cursor.selectionEnd()).blockNumber();
for (int currentBlockNumber = startNumber; currentBlockNumber <= endNumber;
++currentBlockNumber) {
const QTextBlock currentBlock = doc->findBlockByNumber(currentBlockNumber);
if (currentBlock.isValid()) {
const int blocksAmount = doc->blockCount();
indentBlock(doc, currentBlock, typedChar, tabSettings); indentBlock(doc, currentBlock, typedChar, tabSettings);
currentBlock = currentBlock.next(); QTC_CHECK(blocksAmount == doc->blockCount()
&& "ClangFormat plugin indentation changed the amount of blocks.");
}
} }
} else { } else {
indentBlock(doc, cursor.block(), typedChar, tabSettings); indentBlock(doc, cursor.block(), typedChar, tabSettings);
@@ -399,6 +430,7 @@ void ClangFormatIndenter::indentBlock(QTextDocument *doc,
const Utils::FileName fileName = editor->textDocument()->filePath(); const Utils::FileName fileName = editor->textDocument()->filePath();
trimFirstNonEmptyBlock(block); trimFirstNonEmptyBlock(block);
trimCurrentBlock(block);
const QByteArray buffer = doc->toPlainText().toUtf8(); const QByteArray buffer = doc->toPlainText().toUtf8();
const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1); const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1);
QTC_ASSERT(utf8Offset >= 0, return;); QTC_ASSERT(utf8Offset >= 0, return;);
@@ -417,6 +449,7 @@ int ClangFormatIndenter::indentFor(const QTextBlock &block, const TextEditor::Ta
const Utils::FileName fileName = editor->textDocument()->filePath(); const Utils::FileName fileName = editor->textDocument()->filePath();
trimFirstNonEmptyBlock(block); trimFirstNonEmptyBlock(block);
trimCurrentBlock(block);
const QTextDocument *doc = block.document(); const QTextDocument *doc = block.document();
const QByteArray buffer = doc->toPlainText().toUtf8(); const QByteArray buffer = doc->toPlainText().toUtf8();
const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1); const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1);

View File

@@ -177,8 +177,10 @@ void DiagnosticView::setModel(QAbstractItemModel *model)
m_ignoreSetSelectedFixItsCount = false; m_ignoreSetSelectedFixItsCount = false;
}); });
setHeader(clickableFixItHeader); setHeader(clickableFixItHeader);
header()->setStretchLastSection(false); clickableFixItHeader->setStretchLastSection(false);
header()->setSectionResizeMode(0, QHeaderView::Stretch); clickableFixItHeader->setSectionResizeMode(0, QHeaderView::Stretch);
clickableFixItHeader->setSectionResizeMode(1, QHeaderView::ResizeToContents);
clickableFixItHeader->setSectionResizeMode(2, QHeaderView::ResizeToContents);
} }
} // namespace Internal } // namespace Internal

View File

@@ -136,7 +136,7 @@ CppTools::CheckSymbols *createHighlighter(const CPlusPlus::Document::Ptr &doc,
int line, column; int line, column;
convertPosition(textDocument, macro.utf16charsBegin(), &line, &column); convertPosition(textDocument, macro.utf16charsBegin(), &line, &column);
++column; //Highlighting starts at (column-1) --> compensate here
Result use(line, column, name.size(), SemanticHighlighter::MacroUse); Result use(line, column, name.size(), SemanticHighlighter::MacroUse);
macroUses.append(use); macroUses.append(use);
} }

View File

@@ -235,14 +235,15 @@ static int lastIncludeIndex(const QStringList &options, const QRegularExpression
static int includeIndexForResourceDirectory(const QStringList &options, bool isMacOs = false) static int includeIndexForResourceDirectory(const QStringList &options, bool isMacOs = false)
{ {
// include/c++/{version}, include/c++/v1 and include/g++ // include/c++, include/g++, libc++\include and libc++abi\include
static const QRegularExpression includeRegExp( static const QString cppIncludes = R"((.*[\/\\]include[\/\\].*(g\+\+|c\+\+).*))"
R"(\A.*[\/\\]include[\/\\].*(g\+\+.*\z|c\+\+[\/\\](v1\z|\d+.*\z)))"); R"(|(.*libc\+\+[\/\\]include))"
R"(|(.*libc\+\+abi[\/\\]include))";
static const QRegularExpression includeRegExp("\\A(" + cppIncludes + ")\\z");
// The same as includeRegExp but also matches /usr/local/include // The same as includeRegExp but also matches /usr/local/include
static const QRegularExpression includeRegExpMac( static const QRegularExpression includeRegExpMac(
R"(\A(.*[\/\\]include[\/\\].*(g\+\+.*\z|c\+\+[\/\\](v1\z|\d+.*\z))))" "\\A(" + cppIncludes + R"(|([\/\\]usr[\/\\]local[\/\\]include))" + ")\\z");
R"(|([\/\\]usr[\/\\]local[\/\\]include\z))");
const int cppIncludeIndex = lastIncludeIndex(options, isMacOs const int cppIncludeIndex = lastIncludeIndex(options, isMacOs
? includeRegExpMac ? includeRegExpMac

View File

@@ -491,10 +491,13 @@ void FollowSymbolUnderCursor::findLink(
{ {
Link link; Link link;
int line = 0;
int column = 0;
QTextCursor cursor = data.cursor(); QTextCursor cursor = data.cursor();
QTextDocument *document = cursor.document(); QTextDocument *document = cursor.document();
if (!document)
return processLinkCallback(link);
int line = 0;
int column = 0;
Utils::Text::convertPosition(document, cursor.position(), &line, &column); Utils::Text::convertPosition(document, cursor.position(), &line, &column);
const int positionInBlock = column - 1; const int positionInBlock = column - 1;

View File

@@ -384,7 +384,12 @@ void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective)
if (m_currentPerspective) if (m_currentPerspective)
m_currentPerspective->d->restoreLayout(); m_currentPerspective->d->restoreLayout();
const int index = indexInChooser(m_currentPerspective); int index = indexInChooser(m_currentPerspective);
if (index == -1) {
if (Perspective *parent = Perspective::findPerspective(m_currentPerspective->d->m_parentPerspectiveId))
index = indexInChooser(parent);
}
if (index != -1) { if (index != -1) {
m_perspectiveChooser->setCurrentIndex(index); m_perspectiveChooser->setCurrentIndex(index);

View File

@@ -408,6 +408,11 @@ void ThreadsHandler::setThreads(const GdbMi &data)
if (!m_currentThread && threads.childCount() > 0) if (!m_currentThread && threads.childCount() > 0)
m_currentThread = rootItem()->childAt(0); m_currentThread = rootItem()->childAt(0);
if (!m_currentThread) {
const QModelIndex currentThreadIndex = m_currentThread->index();
threadSwitcher()->setCurrentIndex(currentThreadIndex.row());
}
} }
QAbstractItemModel *ThreadsHandler::model() QAbstractItemModel *ThreadsHandler::model()

View File

@@ -396,27 +396,28 @@ ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() con
} else if (a == "-arch") { } else if (a == "-arch") {
if (++iArg < allFlags.length() && !arguments.contains(a)) if (++iArg < allFlags.length() && !arguments.contains(a))
arguments << a << allFlags.at(iArg); arguments << a << allFlags.at(iArg);
} else if (a == "--sysroot" || a == "-isysroot" || a == "-D" ||a == "-U") { } else if (a == "--sysroot" || a == "-isysroot" || a == "-D" || a == "-U"
|| a == "-gcc-toolchain" || a == "-target") {
if (++iArg < allFlags.length()) if (++iArg < allFlags.length())
arguments << a << allFlags.at(iArg); arguments << a << allFlags.at(iArg);
} else if (a == "-m128bit-long-double" || a == "-m32" || a == "-m3dnow" || a == "-m3dnowa" } else if (a == "-m128bit-long-double" || a == "-m32" || a == "-m3dnow"
|| a == "-m64" || a == "-m96bit-long-double" || a == "-mabm" || a == "-maes" || a == "-m3dnowa" || a == "-m64" || a == "-m96bit-long-double"
|| a.startsWith("-march=") || a == "-mavx" || a.startsWith("-masm=") || a == "-mabm" || a == "-maes" || a.startsWith("-march=") || a == "-mavx"
|| a.startsWith("-mfloat-abi") || a.startsWith("-masm=") || a.startsWith("-mfloat-abi") || a == "-mcx16"
|| a == "-mcx16" || a == "-mfma" || a == "-mfma4" || a == "-mlwp" || a == "-mfma" || a == "-mfma4" || a == "-mlwp" || a == "-mpclmul"
|| a == "-mpclmul" || a == "-mpopcnt" || a == "-msse" || a == "-msse2" || a == "-mpopcnt" || a == "-msse" || a == "-msse2" || a == "-msse2avx"
|| a == "-msse2avx" || a == "-msse3" || a == "-msse4" || a == "-msse4.1" || a == "-msse3" || a == "-msse4" || a == "-msse4.1" || a == "-msse4.2"
|| a == "-msse4.2" || a == "-msse4a" || a == "-mssse3" || a == "-msse4a" || a == "-mssse3" || a.startsWith("-mtune=")
|| a.startsWith("-mtune=") || a == "-mxop" || a == "-mxop" || a == "-Os" || a == "-O0" || a == "-O1" || a == "-O2"
|| a == "-Os" || a == "-O0" || a == "-O1" || a == "-O2" || a == "-O3" || a == "-O3" || a == "-ffinite-math-only" || a == "-fshort-double"
|| a == "-ffinite-math-only" || a == "-fshort-double" || a == "-fshort-wchar" || a == "-fshort-wchar" || a == "-fsignaling-nans" || a == "-fno-inline"
|| a == "-fsignaling-nans" || a == "-fno-inline" || a == "-fno-exceptions" || a == "-fno-exceptions" || a == "-fstack-protector"
|| a == "-fstack-protector" || a == "-fstack-protector-all" || a == "-fstack-protector-all" || a == "-fsanitize=address"
|| a == "-fsanitize=address" || a == "-fno-rtti" || a == "-fno-rtti" || a.startsWith("-std=") || a.startsWith("-stdlib=")
|| a.startsWith("-std=") || a.startsWith("-stdlib=") || a.startsWith("-specs=") || a.startsWith("-specs=") || a == "-ansi" || a == "-undef"
|| a == "-ansi" || a == "-undef" || a.startsWith("-D") || a.startsWith("-U") || a.startsWith("-D") || a.startsWith("-U") || a == "-fopenmp"
|| a == "-fopenmp" || a == "-Wno-deprecated" || a == "-fPIC" || a == "-fpic" || a == "-Wno-deprecated" || a == "-fPIC" || a == "-fpic" || a == "-fPIE"
|| a == "-fPIE" || a == "-fpie") || a == "-fpie")
arguments << a; arguments << a;
} }
@@ -545,13 +546,14 @@ QStringList GccToolChain::gccPrepareArguments(const QStringList &flags,
for (int i = 0; i < allFlags.size(); ++i) { for (int i = 0; i < allFlags.size(); ++i) {
const QString &flag = allFlags.at(i); const QString &flag = allFlags.at(i);
if (flag.startsWith("-stdlib=") || flag.startsWith("--gcctoolchain=") if (flag.startsWith("-stdlib=") || flag.startsWith("--gcctoolchain=")
|| flag.startsWith("-B")) { || flag.startsWith("-B") || (flag.startsWith("-isystem") && flag.length() > 8)) {
arguments << flag; arguments << flag;
} else if (!hasKitSysroot) { } else if (!hasKitSysroot) {
// pass build system's sysroot to compiler, if we didn't pass one from kit // pass build system's sysroot to compiler, if we didn't pass one from kit
if (flag.startsWith("--sysroot=")) { if (flag.startsWith("--sysroot=")) {
arguments << flag; arguments << flag;
} else if ((flag.startsWith("-isysroot") || flag.startsWith("--sysroot")) } else if ((flag.startsWith("-isysroot") || flag.startsWith("--sysroot")
|| flag == "-target" || flag == "-gcc-toolchain" || flag == "-isystem")
&& i < flags.size() - 1) { && i < flags.size() - 1) {
arguments << flag << allFlags.at(i + 1); arguments << flag << allFlags.at(i + 1);
++i; ++i;

View File

@@ -437,12 +437,12 @@ void TaskFilterModel::handleRowsAboutToBeRemoved(const QModelIndex &index, int f
QTC_ASSERT(!index.isValid(), return); QTC_ASSERT(!index.isValid(), return);
const QPair<int, int> range = findFilteredRange(first, last, m_mapping); const QPair<int, int> range = findFilteredRange(first, last, m_mapping);
if (range.first > range.second) // rows to be removed are filtered out if (range.first <= range.second) { // remove corresponding rows in filtermodel
return;
beginRemoveRows(QModelIndex(), range.first, range.second); beginRemoveRows(QModelIndex(), range.first, range.second);
m_beginRemoveRowsSent = true; m_beginRemoveRowsSent = true;
m_mapping.erase(m_mapping.begin() + range.first, m_mapping.begin() + range.second + 1); m_mapping.erase(m_mapping.begin() + range.first, m_mapping.begin() + range.second + 1);
}
// adapt existing mapping to removed source indices
const int sourceRemovedCount = (last - first) + 1; const int sourceRemovedCount = (last - first) + 1;
for (int i = range.first; i < m_mapping.count(); ++i) for (int i = range.first; i < m_mapping.count(); ++i)
m_mapping[i] = m_mapping.at(i) - sourceRemovedCount; m_mapping[i] = m_mapping.at(i) - sourceRemovedCount;

View File

@@ -289,7 +289,12 @@ bool ToolChain::fromMap(const QVariantMap &data)
static long toLanguageVersionAsLong(QByteArray dateAsByteArray) static long toLanguageVersionAsLong(QByteArray dateAsByteArray)
{ {
dateAsByteArray.chop(1); // Strip 'L'. dateAsByteArray.chop(1); // Strip 'L'.
return dateAsByteArray.toLong(nullptr);
bool success = false;
const int result = dateAsByteArray.toLong(&success);
QTC_CHECK(success);
return result;
} }
LanguageVersion ToolChain::cxxLanguageVersion(const QByteArray &cplusplusMacroValue) LanguageVersion ToolChain::cxxLanguageVersion(const QByteArray &cplusplusMacroValue)

View File

@@ -63,8 +63,7 @@ void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant
timelineFrames.setValue(value, frame); timelineFrames.setValue(value, frame);
return; return;
} else if (timelineIsActive()) { } else if (modelNode().hasId() && timelineIsActive()) {
QmlTimelineKeyframeGroup timelineFrames(currentTimeline().keyframeGroup(modelNode(), name)); QmlTimelineKeyframeGroup timelineFrames(currentTimeline().keyframeGroup(modelNode(), name));
Q_ASSERT(timelineFrames.isValid()); Q_ASSERT(timelineFrames.isValid());

View File

@@ -57,6 +57,11 @@
\" <comment>JSON file</comment>\", \" <comment>JSON file</comment>\",
\" <glob pattern=\'*.json\' weight=\'70\'/>\", \" <glob pattern=\'*.json\' weight=\'70\'/>\",
\" </mime-type>\", \" </mime-type>\",
\" <mime-type type=\'application/x-javascript-module\'>\",
\" <sub-class-of type=\'application/javascript\'/>\",
\" <comment>Javascript module</comment>\",
\" <glob pattern=\'*.mjs\' weight=\'70\'/>\",
\" </mime-type>\",
\"</mime-info>\" \"</mime-info>\"
] ]
} }

View File

@@ -1,40 +1,40 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<instructionals module="Qt"> <instructionals module="Qt">
<tutorials> <tutorials>
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-build-example-application.html" projectPath="" name="Help: Build and Run Examples"> <tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-build-example-application.html" projectPath="" name="Help: Building and Running an Example">
<description><![CDATA[Testing that your installation is successful by opening an existing example application project.]]></description> <description><![CDATA[Testing that your installation is successful by opening an existing example application project.]]></description>
<tags>qt creator,build,compile,help</tags> <tags>qt creator,build,compile,help</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-writing-program.html" projectPath="" name="Help: Create Qt Widget-Based Applications"> <tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-writing-program.html" projectPath="" name="Help: Creating a Qt Widget-Based Application">
<description><![CDATA[Using Qt Creator to create a small Qt application, Text Finder.]]></description> <description><![CDATA[Using Qt Creator to create a small Qt application, Text Finder.]]></description>
<tags>qt creator,qt designer,widgets,c++,text,help</tags> <tags>qt creator,qt designer,widgets,c++,text,help</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtdoc/qtdoc/gettingstartedqt.html" projectPath="" name="Help: Program with Qt Widgets"> <tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtdoc/qtdoc/qtwidgets-tutorials-notepad-example.html" projectPath="" name="Help: Getting Started Programming with Qt Widgets">
<description><![CDATA[Developing Qt applications using C++ and the Qt Widgets module.]]></description> <description><![CDATA[Developing Qt applications using C++ and the Qt Widgets module.]]></description>
<tags>qt,qt creator,qt designer,widgets,c++,help</tags> <tags>qt,qt creator,qt designer,widgets,c++,help</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qt-creator-transitions-example.html" projectPath="" name="Help: Create Qt Quick Applications"> <tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qt-creator-transitions-example.html" projectPath="" name="Help: Creating a Qt Quick Application">
<description><![CDATA[Using basic QML elements and learning about basic concepts of Qt Quick.]]></description> <description><![CDATA[Using basic QML elements and learning about basic concepts of Qt Quick.]]></description>
<tags>qt creator,qt quick designer,qt quick,qml,states,transitions,help</tags> <tags>qt creator,qt quick designer,qt quick,qml,states,transitions,help</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qt-creator-accelbubble-example.html" projectPath="" name="Help: Create Mobile Qt Applications"> <tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qt-creator-accelbubble-example.html" projectPath="" name="Help: Creating a Mobile Qt Application">
<description><![CDATA[Developing Qt Quick applications for Android and iOS devices using Qt Quick Controls.]]></description> <description><![CDATA[Developing Qt Quick applications for Android and iOS devices using Qt Quick Controls.]]></description>
<tags>qt creator,qt quick designer,qml,android,ios,controls,help</tags> <tags>qt creator,qt quick designer,qml,android,ios,controls,help</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtdoc/qtdoc/gettingstartedqml.html" projectPath="" name="Help: Program with Qt Quick"> <tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtdoc/qtdoc/gettingstartedqml.html" projectPath="" name="Help: Getting Started Programming with Qt Quick">
<description><![CDATA[Developing Qt Quick applications using QML and C++.]]></description> <description><![CDATA[Developing Qt Quick applications using QML and C++.]]></description>
<tags>qt quick,qml,c++,help</tags> <tags>qt quick,qml,c++,help</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Digital Instrument Cluster and Qt Safe Renderer" isVideo="true" videoUrl="https://www.youtube.com/watch?v=9RxxsOCeZHk" videoLength="4:06"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Digital Instrument Cluster with Qt Quick Designer and Qt Safe Renderer" isVideo="true" videoUrl="https://www.youtube.com/watch?v=9RxxsOCeZHk" videoLength="4:06">
<description><![CDATA[Creating a digital instrument cluster with Qt Quick Designer and Qt Safe Renderer.]]></description> <description><![CDATA[Creating a digital instrument cluster with Qt Quick Designer and Qt Safe Renderer.]]></description>
<tags>qt creator,qt quick,automotive,safe renderer,controls,video</tags> <tags>qt creator,qt quick,automotive,safe renderer,controls,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt for Device Creation - Overview" isVideo="true" videoUrl="https://www.youtube.com/watch?v=PercN_GtVJA" videoLength="3:01"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=PercN_GtVJA" videoLength="3:01">
<description><![CDATA[Creating a Qt widget based application.]]></description> <description><![CDATA[Creating a Qt widget based application.]]></description>
<tags>qt creator,embedded,device creation,video</tags> <tags>qt creator,embedded,device creation,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt for Device Creation - Getting Started" isVideo="true" videoUrl="https://www.youtube.com/watch?v=QFWPw4UWL9E" videoLength="8:30"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Getting Started - Qt for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=QFWPw4UWL9E" videoLength="8:30">
<description><![CDATA[Using Qt Creator to deploy applications to an embedded device.]]></description> <description><![CDATA[Using Qt Creator to deploy applications to an embedded device.]]></description>
<tags>qt creator,embedded,device creation,video</tags> <tags>qt creator,embedded,device creation,video</tags>
</tutorial> </tutorial>
@@ -50,23 +50,23 @@
<description><![CDATA[Creating a Qt Quick application.]]></description> <description><![CDATA[Creating a Qt Quick application.]]></description>
<tags>qt creator,qt quick,video</tags> <tags>qt creator,qt quick,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt SCXML and Tooling in Qt Creator" isVideo="true" videoUrl="https://youtu.be/9xqhq9nDiOg" videoLength="4:53"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt SCXML and State Machine Tooling in Qt Creator" isVideo="true" videoUrl="https://youtu.be/9xqhq9nDiOg" videoLength="4:53">
<description><![CDATA[Creating state machines.]]></description> <description><![CDATA[Creating state machines.]]></description>
<tags>qt creator,SCXML,video</tags> <tags>qt creator,SCXML,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Using C++ Models in QML" isVideo="true" videoUrl="https://www.youtube.com/watch?v=9BcAYDlpuT8" videoLength="49:48"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Using C++ Models in QML - To-do List" isVideo="true" videoUrl="https://www.youtube.com/watch?v=9BcAYDlpuT8" videoLength="49:48">
<description><![CDATA[Creating and using a C++ model in QML.]]></description> <description><![CDATA[Creating and using a C++ model in QML.]]></description>
<tags>qt creator,qt quick,c++,video</tags> <tags>qt creator,qt quick,c++,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Creator - Overview" isVideo="true" videoUrl="https://youtu.be/zAqSiIGdj8M" videoLength="2:06"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Creator - Meet Qt Creator" isVideo="true" videoUrl="https://youtu.be/zAqSiIGdj8M" videoLength="2:06">
<description><![CDATA[Overview of Qt Creator.]]></description> <description><![CDATA[Overview of Qt Creator.]]></description>
<tags>qt creator,video</tags> <tags>qt creator,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Creator - Introduction" isVideo="true" videoUrl="https://www.youtube.com/watch?v=R6zWLfHIYJw" videoLength="9:29"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Creator - Examples" isVideo="true" videoUrl="https://www.youtube.com/watch?v=R6zWLfHIYJw" videoLength="9:29">
<description><![CDATA[Using Qt Creator tutorials and examples to develop Qt applications.]]></description> <description><![CDATA[Using Qt Creator tutorials and examples to develop Qt applications.]]></description>
<tags>qt creator,video</tags> <tags>qt creator,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Creator - Using Qt Quick Designer" isVideo="true" videoUrl="https://www.youtube.com/watch?v=0Po3tE9yUcU" videoLength="7:36"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Creator - UI Design with Qt Quick Designer" isVideo="true" videoUrl="https://www.youtube.com/watch?v=0Po3tE9yUcU" videoLength="7:36">
<description><![CDATA[Using Qt Quick Designer to develop Qt Quick applications.]]></description> <description><![CDATA[Using Qt Quick Designer to develop Qt Quick applications.]]></description>
<tags>qt creator,qt quick,video</tags> <tags>qt creator,qt quick,video</tags>
</tutorial> </tutorial>
@@ -74,20 +74,20 @@
<description><![CDATA[Using signals, slots, and property bindings Qt Quick applications.]]></description> <description><![CDATA[Using signals, slots, and property bindings Qt Quick applications.]]></description>
<tags>qt creator,qt quick,qml,video</tags> <tags>qt creator,qt quick,qml,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Quick Designer - Qt Quick Controls" isVideo="true" videoUrl="https://www.youtube.com/watch?v=uuhmSZxK1mk" videoLength="7:09"> <tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Creator - Introduction to Qt Quick Controls" isVideo="true" videoUrl="https://www.youtube.com/watch?v=uuhmSZxK1mk" videoLength="7:09">
<description><![CDATA[Using Qt Quick Controls to develop Qt Quick applications.]]></description> <description><![CDATA[Using Qt Quick Controls to develop Qt Quick applications.]]></description>
<tags>qt creator,qt quick,controls,video</tags> <tags>qt creator,qt quick,controls,video</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Getting Started" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nGFmjOiT22Y" videoLength="50:36"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Introduction to Qt Creator" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nGFmjOiT22Y" videoLength="50:36">
<description><![CDATA[Getting started with using Qt Creator for cross-platform development.]]></description> <description><![CDATA[Getting started with using Qt Creator for cross-platform development.]]></description>
<tags>qt creator,talk,2015</tags> <tags>qt creator,talk,2015</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Custom Wizards" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Ko3DuCgFamo" videoLength="27:21"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Custom Qt Creator Wizards" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Ko3DuCgFamo" videoLength="27:21">
<description><![CDATA[Adding custom file and project creation wizards to Qt Creator.]]></description> <description><![CDATA[Adding custom file and project creation wizards to Qt Creator.]]></description>
<tags>qt creator,wizard,talk,2015</tags> <tags>qt creator,wizard,talk,2015</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Extending Without Writing Code" isVideo="true" videoUrl="http://www.youtube.com/watch?v=DP0lMoLVneY" videoLength="59:49"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Extending Qt Creator" isVideo="true" videoUrl="http://www.youtube.com/watch?v=DP0lMoLVneY" videoLength="59:49">
<description><![CDATA[Customizing Qt Creator to fit your own or your customers' purposes.]]></description> <description><![CDATA[Customizing Qt Creator to fit your own or your customers' purposes.]]></description>
<tags>qt creator,configuration,talk,2013</tags> <tags>qt creator,configuration,talk,2013</tags>
</tutorial> </tutorial>
@@ -95,48 +95,48 @@
<description><![CDATA[Adding plugins to Qt Creator.]]></description> <description><![CDATA[Adding plugins to Qt Creator.]]></description>
<tags>qt creator,plugins,talk,2013</tags> <tags>qt creator,plugins,talk,2013</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - QML Profiler" isVideo="true" videoUrl="https://www.youtube.com/watch?v=TiJiF0MOOFc" videoLength="55:12"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Using the QML Profiler" isVideo="true" videoUrl="https://www.youtube.com/watch?v=TiJiF0MOOFc" videoLength="55:12">
<description><![CDATA[Monitoring the performance of a Qt Quick application.]]></description> <description><![CDATA[Monitoring the performance of a Qt Quick application.]]></description>
<tags>qt quick,qt creator,qml profiler,talk,2014</tags> <tags>qt quick,qt creator,qml profiler,talk,2014</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - CPU Usage Analyzer" isVideo="true" videoUrl="https://www.youtube.com/watch?v=G0AbgVHGdXI" videoLength="22:30"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: The CPU Usage Analyzer for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=G0AbgVHGdXI" videoLength="22:30">
<description><![CDATA[Using the Linux perf tool to generate data for code analysis.]]></description> <description><![CDATA[Using the Linux perf tool to generate data for code analysis.]]></description>
<tags>qt creator,cpu usage analyzer,perf,embedded,device creation,talk,2015</tags> <tags>qt creator,cpu usage analyzer,perf,embedded,device creation,talk,2015</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - SCXML Editor" isVideo="true" videoUrl="https://youtu.be/X0kEkB0ewyw" videoLength="42:22"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt SCXML - State Machines Made Easier" isVideo="true" videoUrl="https://youtu.be/X0kEkB0ewyw" videoLength="42:22">
<description><![CDATA[Using the Qt SCXML module and Qt Creator SCXML editor.]]></description> <description><![CDATA[Using the Qt SCXML module and Qt Creator SCXML editor.]]></description>
<tags>qt creator,scxml,talk,2016</tags> <tags>qt creator,scxml,talk,2016</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Multi-Platform Development" isVideo="true" videoUrl="https://www.youtube.com/watch?v=v4glCQt2jE0" videoLength="19:08"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Effective Multi-Platform Development with Qt Creator, QBS, and QEMU" isVideo="true" videoUrl="https://www.youtube.com/watch?v=v4glCQt2jE0" videoLength="19:08">
<description><![CDATA[Using Qt Creator, Qbs, and QEMU for application development.]]></description> <description><![CDATA[Using Qt Creator, Qbs, and QEMU for application development.]]></description>
<tags>qt creator,qbs,qemu,talk,2015</tags> <tags>qt creator,qbs,qemu,talk,2015</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on Android - Overview" isVideo="true" videoUrl="https://youtu.be/dmKNxyi_YNk" videoLength="31:20"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: All About Qt on Android" isVideo="true" videoUrl="https://youtu.be/dmKNxyi_YNk" videoLength="31:20">
<description><![CDATA[Developing Qt applications for Android devices.]]></description> <description><![CDATA[Developing Qt applications for Android devices.]]></description>
<tags>qt creator,android,talk,2016</tags> <tags>qt creator,android,talk,2016</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on iOS - Overview" isVideo="true" videoUrl="https://youtu.be/T_13aX5NTPk" videoLength="1:00:13"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt for iOS - A to Z" isVideo="true" videoUrl="https://youtu.be/T_13aX5NTPk" videoLength="1:00:13">
<description><![CDATA[Developing Qt applications for iOS.]]></description> <description><![CDATA[Developing Qt applications for iOS.]]></description>
<tags>qt creator,ios,talk,2016</tags> <tags>qt creator,ios,talk,2016</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Bare Metal Development" isVideo="true" videoUrl="http://www.youtube.com/watch?v=hrKz63Q_Rf0" videoLength="9:35"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator for Bare Metal Development" isVideo="true" videoUrl="http://www.youtube.com/watch?v=hrKz63Q_Rf0" videoLength="9:35">
<description><![CDATA[Developing Qt Applications for Bare Metal devices.]]></description> <description><![CDATA[Developing Qt Applications for Bare Metal devices.]]></description>
<tags>qt creator,baremetal,talk,2013</tags> <tags>qt creator,baremetal,talk,2013</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on Universal Windows Platform" isVideo="true" videoUrl="https://youtu.be/tpNdw2Cs4KY" videoLength="47:38"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Integrating Universal Windows Platform to Qt" isVideo="true" videoUrl="https://youtu.be/tpNdw2Cs4KY" videoLength="47:38">
<description><![CDATA[Qt support for Universal Windows Platform on desktop, mobile, and embedded devices.]]></description> <description><![CDATA[Qt support for Universal Windows Platform on desktop, mobile, and embedded devices.]]></description>
<tags>uwp,talk,2016</tags> <tags>uwp,talk,2016</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Quick Controls 2 - Overview" isVideo="true" videoUrl="https://youtu.be/ozpSl7WbVt4" videoLength="23:13"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Developing User Interfaces with Qt Quick Controls 2" isVideo="true" videoUrl="https://youtu.be/ozpSl7WbVt4" videoLength="23:13">
<description><![CDATA[Using Qt Quick Controls 2 to create UIs.]]></description> <description><![CDATA[Using Qt Quick Controls 2 to create UIs.]]></description>
<tags>ui,qt quick designer,controls,ui,talk,2016</tags> <tags>ui,qt quick designer,controls,ui,talk,2016</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: GUI technologies in Qt" isVideo="true" videoUrl="https://youtu.be/WIRRoPxIerc" videoLength="40:45"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: The Curse of Choice - An Overview of GUI Technologies in Qt" isVideo="true" videoUrl="https://youtu.be/WIRRoPxIerc" videoLength="40:45">
<description><![CDATA[Overview of UI technologies that can be used with Qt.]]></description> <description><![CDATA[Overview of UI technologies that can be used with Qt.]]></description>
<tags>qt quick,ui,widgets,talk,2016</tags> <tags>qt quick,ui,widgets,talk,2016</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on Android Wear" isVideo="true" videoUrl="https://youtu.be/Rd187QxihRo" videoLength="8:08"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on Your Wrist" isVideo="true" videoUrl="https://youtu.be/Rd187QxihRo" videoLength="8:08">
<description><![CDATA[Running Qt apps on Android Wear devices.]]></description> <description><![CDATA[Running Qt apps on Android Wear devices.]]></description>
<tags>qt creator,android,talk,2016</tags> <tags>qt creator,android,talk,2016</tags>
</tutorial> </tutorial>
@@ -144,40 +144,40 @@
<description><![CDATA[Using Qt with macOS native windows.]]></description> <description><![CDATA[Using Qt with macOS native windows.]]></description>
<tags>macos,talk,2016</tags> <tags>macos,talk,2016</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Multi-Platform and Screen Resolution" isVideo="true" videoUrl="https://youtu.be/qclquZ99ZVQ" videoLength="27:44"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: How to Develop with Qt for Multiple Screen Resolutions and Platforms and Best Practices for an Efficient App Lifecycle with Qt" isVideo="true" videoUrl="https://youtu.be/qclquZ99ZVQ" videoLength="27:44">
<description><![CDATA[Best practices for an efficient app lifecycle.]]></description> <description><![CDATA[Best practices for an efficient app lifecycle.]]></description>
<tags>qt,qt quick,screen resolution,ui,talk,2016</tags> <tags>qt,qt quick,screen resolution,ui,talk,2016</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Mobile Applications - Tips and Examples" isVideo="true" videoUrl="https://www.youtube.com/watch?v=OqqarK73I9E" videoLength="53:57"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: App Development with Qt - Technical Tips and Examples for Development & Testing" isVideo="true" videoUrl="https://www.youtube.com/watch?v=OqqarK73I9E" videoLength="53:57">
<description><![CDATA[Technical tips and examples for developing and testing mobile apps.]]></description> <description><![CDATA[Technical tips and examples for developing and testing mobile apps.]]></description>
<tags>android,ios,talk,2017</tags> <tags>android,ios,talk,2017</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt in Medical Devices - Overview" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Xe5xebP9w94" videoLength="24:53"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Technical Overview of Qt in Medical Devices" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Xe5xebP9w94" videoLength="24:53">
<description><![CDATA[Developing UX and UI for medical devices.]]></description> <description><![CDATA[Developing UX and UI for medical devices.]]></description>
<tags>medical,ui,talk,2017</tags> <tags>medical,ui,talk,2017</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Mobile Applications - Reducing Size" isVideo="true" videoUrl="https://www.youtube.com/watch?v=3o2Wo4YzlII" videoLength="23:41"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Android & iOS - Put Your App on a Diet" isVideo="true" videoUrl="https://www.youtube.com/watch?v=3o2Wo4YzlII" videoLength="23:41">
<description><![CDATA[Making Android and iOS apps smaller.]]></description> <description><![CDATA[Making Android and iOS apps smaller.]]></description>
<tags>android,ios,talk,2017</tags> <tags>android,ios,talk,2017</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Automotive Suite - Overview" isVideo="true" videoUrl="https://www.youtube.com/watch?v=7FqG2lpJ1KE" videoLength="23:38"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Under the Hood of Qt Automotive Suite After One Year of Hacking" isVideo="true" videoUrl="https://www.youtube.com/watch?v=7FqG2lpJ1KE" videoLength="23:38">
<description><![CDATA[Introducing Qt Application Manager plugin in Qt Creator.]]></description> <description><![CDATA[Introducing Qt Application Manager plugin in Qt Creator.]]></description>
<tags>automotive,application manager,talk,2017</tags> <tags>automotive,application manager,talk,2017</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Embedded Devices - Virtual Keyboards" isVideo="true" videoUrl="https://www.youtube.com/watch?v=g0X2IZ9ZCTA" videoLength="19:32"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Using Virtual Keyboards on Qt Embedded Devices" isVideo="true" videoUrl="https://www.youtube.com/watch?v=g0X2IZ9ZCTA" videoLength="19:32">
<description><![CDATA[Support text input via virtual keyboards on embedded devices.]]></description> <description><![CDATA[Support text input via virtual keyboards on embedded devices.]]></description>
<tags>embedded,virtual keyboard,talk,2017</tags> <tags>embedded,virtual keyboard,talk,2017</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Quick Controls 2 - Mobile Business Applications" isVideo="true" videoUrl="https://www.youtube.com/watch?v=au3brB7lNms" videoLength="23:33"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: No Limits - How to Make an More Complicated Mobile Business App" isVideo="true" videoUrl="https://www.youtube.com/watch?v=au3brB7lNms" videoLength="23:33">
<description><![CDATA[Creating mobile business apps using Qt Quick Controls 2.]]></description> <description><![CDATA[Creating mobile business apps using Qt Quick Controls 2.]]></description>
<tags>android,ios,qt quick,controls,talk,2017</tags> <tags>android,ios,qt quick,controls,talk,2017</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Automotive Suite - Qt IVI" isVideo="true" videoUrl="https://www.youtube.com/watch?v=CVhVAK10TDw" videoLength="46:41"> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt IVI - Integrating and Testing Vechile Functions with Qt Automotive Suite 1.3" isVideo="true" videoUrl="https://www.youtube.com/watch?v=CVhVAK10TDw" videoLength="46:41">
<description><![CDATA[Integrating and testing vehicle functions with Qt Automotive Suite.]]></description> <description><![CDATA[Integrating and testing vehicle functions with Qt Automotive Suite.]]></description>
<tags>automotive,ivi,talk,2017</tags> <tags>automotive,ivi,talk,2017</tags>
</tutorial> </tutorial>
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt 3D - Simple and Skeletal Animations" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Cj5enhBlL28" videoLength=""> <tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Breathing Life into Your Applications - Animation with Qt 3D" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Cj5enhBlL28" videoLength="">
<description><![CDATA[Using the new animation subsystem of Qt 3D.]]></description> <description><![CDATA[Using the new animation subsystem of Qt 3D.]]></description>
<tags>talk,2017</tags> <tags>talk,2017</tags>
</tutorial> </tutorial>

View File

@@ -76,10 +76,14 @@ void BaseHoverHandler::contextHelpId(TextEditorWidget *widget,
{ {
// If the tooltip is visible and there is a help match, this match is used to update // If the tooltip is visible and there is a help match, this match is used to update
// the help id. Otherwise, let the identification process happen. // the help id. Otherwise, let the identification process happen.
if (!Utils::ToolTip::isVisible() || !lastHelpItemIdentified().isValid()) if (!Utils::ToolTip::isVisible() || !lastHelpItemIdentified().isValid()) {
process(widget, pos, [this, widget, callback](int) { propagateHelpId(widget, callback); }); process(widget, pos, [this, widget = QPointer<TextEditorWidget>(widget), callback](int) {
else if (widget)
propagateHelpId(widget, callback); propagateHelpId(widget, callback);
});
} else {
propagateHelpId(widget, callback);
}
} }
void BaseHoverHandler::setToolTip(const QString &tooltip) void BaseHoverHandler::setToolTip(const QString &tooltip)

View File

@@ -299,6 +299,8 @@ public:
{ {
} }
~HoverHandlerRunner() { abortHandlers(); }
void startChecking(const QTextCursor &textCursor, const QPoint &point) void startChecking(const QTextCursor &textCursor, const QPoint &point)
{ {
if (m_handlers.empty()) if (m_handlers.empty())
@@ -315,9 +317,7 @@ public:
if (isCheckRunning(documentRevision, position)) if (isCheckRunning(documentRevision, position))
return; return;
// Cancel currently running checks abortHandlers();
for (BaseHoverHandler *handler : m_handlers)
handler->abort();
// Update invocation data // Update invocation data
m_documentRevision = documentRevision; m_documentRevision = documentRevision;
@@ -352,8 +352,6 @@ public:
void onHandlerFinished(int documentRevision, int position, int priority) void onHandlerFinished(int documentRevision, int position, int priority)
{ {
if (!m_widget)
return;
QTC_ASSERT(m_currentHandlerIndex < m_handlers.size(), return); QTC_ASSERT(m_currentHandlerIndex < m_handlers.size(), return);
QTC_ASSERT(documentRevision == m_documentRevision, return); QTC_ASSERT(documentRevision == m_documentRevision, return);
QTC_ASSERT(position == m_position, return); QTC_ASSERT(position == m_position, return);
@@ -379,7 +377,13 @@ public:
} }
private: private:
QPointer<TextEditorWidget> m_widget; void abortHandlers()
{
for (BaseHoverHandler *handler : m_handlers)
handler->abort();
}
TextEditorWidget *m_widget;
const QList<BaseHoverHandler *> &m_handlers; const QList<BaseHoverHandler *> &m_handlers;
struct LastHandlerInfo { struct LastHandlerInfo {
@@ -3025,14 +3029,6 @@ void TextEditorWidget::contextMenuEvent(QContextMenuEvent *e)
void TextEditorWidget::inputMethodEvent(QInputMethodEvent *e) void TextEditorWidget::inputMethodEvent(QInputMethodEvent *e)
{ {
if (e->commitString().isEmpty() && e->preeditString().isEmpty() && e->attributes().isEmpty()) {
// Avoid doing anything when getting bogus events as it can happen on Gnome desktop.
// Otherwise QPlainTextEdit will report content changes for locations where factually
// nothing changed.
// Workaround for QTCREATORBUG-19571
e->accept();
return;
}
if (d->m_inBlockSelectionMode) { if (d->m_inBlockSelectionMode) {
if (!e->commitString().isEmpty()) if (!e->commitString().isEmpty())
d->insertIntoBlockSelection(e->commitString()); d->insertIntoBlockSelection(e->commitString());

View File

@@ -111,6 +111,17 @@ defineReplace(splitFlags) {
return($$result) return($$result)
} }
defineReplace(extractWarnings) {
flags = $$1
result =
for (flag, flags) {
contains(flag, ^[-/][wW].*$) {
result += $$flag
}
}
return($$result)
}
CLANGTOOLING_LIBS=-lclangTooling -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \ CLANGTOOLING_LIBS=-lclangTooling -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \
-lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \ -lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \
-lclangASTMatchers -lclangToolingCore -lclangAST -lclangLex -lclangBasic -lclangASTMatchers -lclangToolingCore -lclangAST -lclangLex -lclangBasic
@@ -230,6 +241,9 @@ isEmpty(LLVM_VERSION) {
LLVM_CXXFLAGS ~= s,-Wcovered-switch-default, LLVM_CXXFLAGS ~= s,-Wcovered-switch-default,
LLVM_CXXFLAGS ~= s,-Wnon-virtual-dtor, LLVM_CXXFLAGS ~= s,-Wnon-virtual-dtor,
LLVM_CXXFLAGS ~= s,-Woverloaded-virtual, LLVM_CXXFLAGS ~= s,-Woverloaded-virtual,
LLVM_CXXFLAGS ~= s,-Wmissing-field-initializers,
LLVM_CXXFLAGS ~= s,-Wno-unknown-warning,
LLVM_CXXFLAGS ~= s,-Wno-unused-command-line-argument,
LLVM_CXXFLAGS ~= s,-fPIC, LLVM_CXXFLAGS ~= s,-fPIC,
LLVM_CXXFLAGS ~= s,-pedantic, LLVM_CXXFLAGS ~= s,-pedantic,
LLVM_CXXFLAGS ~= s,-Wstring-conversion, LLVM_CXXFLAGS ~= s,-Wstring-conversion,
@@ -238,6 +252,9 @@ isEmpty(LLVM_VERSION) {
LLVM_CXXFLAGS = $$splitFlags($$LLVM_CXXFLAGS) LLVM_CXXFLAGS = $$splitFlags($$LLVM_CXXFLAGS)
LLVM_CXXFLAGS_WARNINGS = $$extractWarnings($$LLVM_CXXFLAGS)
LLVM_CXXFLAGS -= $$LLVM_CXXFLAGS_WARNINGS
LLVM_IS_COMPILED_WITH_RTTI = $$system($$llvm_config --has-rtti, lines) LLVM_IS_COMPILED_WITH_RTTI = $$system($$llvm_config --has-rtti, lines)
unix:!disable_external_rpath:!contains(QMAKE_DEFAULT_LIBDIRS, $${LLVM_LIBDIR}) { unix:!disable_external_rpath:!contains(QMAKE_DEFAULT_LIBDIRS, $${LLVM_LIBDIR}) {

View File

@@ -106,10 +106,10 @@ int QMakeVfs::idForFileName(const QString &fn, VfsFlags flags)
return id; return id;
} }
#endif #endif
if (!(flags & VfsAccessedOnly)) {
#ifdef PROPARSER_THREAD_SAFE #ifdef PROPARSER_THREAD_SAFE
QMutexLocker locker(&s_mutex); QMutexLocker locker(&s_mutex);
#endif #endif
if (!(flags & VfsAccessedOnly)) {
int &id = s_fileIdMap[fn]; int &id = s_fileIdMap[fn];
if (!id) { if (!id) {
id = ++s_fileIdCounter; id = ++s_fileIdCounter;

View File

@@ -80,6 +80,8 @@ int main(int argc, char *argv[])
const QString connection = processArguments(application); const QString connection = processArguments(application);
// Printing the stack strace might dead lock as clang's stack printer allocates memory.
if (qEnvironmentVariableIntValue("QTC_CLANG_ENABLE_STACKTRACES"))
clang_enableStackTraces(); clang_enableStackTraces();
ClangCodeModelServer clangCodeModelServer; ClangCodeModelServer clangCodeModelServer;

View File

@@ -548,9 +548,6 @@ void TokenInfo::punctuationOrOperatorKind()
// case CXCursor_CXXDeleteExpr: // case CXCursor_CXXDeleteExpr:
overloadedOperatorKind(); overloadedOperatorKind();
break; break;
case CXCursor_Constructor:
collectOutputArguments(m_originalCursor);
break;
case CXCursor_UnaryOperator: case CXCursor_UnaryOperator:
case CXCursor_BinaryOperator: case CXCursor_BinaryOperator:
case CXCursor_CompoundAssignOperator: case CXCursor_CompoundAssignOperator:

View File

@@ -83,7 +83,8 @@ bool UnsavedFile::hasCharacterAt(uint line, uint column, char character) const
Utf8String UnsavedFile::lineRange(uint fromLine, uint toLine) const Utf8String UnsavedFile::lineRange(uint fromLine, uint toLine) const
{ {
QTC_ASSERT(fromLine <= toLine, return Utf8String()); if (fromLine > toLine)
return Utf8String();
// Find start of first line // Find start of first line
bool ok = false; bool ok = false;

View File

@@ -18,7 +18,8 @@ QT -= gui
LIBS += $$LIBTOOLING_LIBS LIBS += $$LIBTOOLING_LIBS
INCLUDEPATH += $$LLVM_INCLUDEPATH INCLUDEPATH += $$LLVM_INCLUDEPATH
QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS QMAKE_CXXFLAGS_WARN_ON *= $$LLVM_CXXFLAGS_WARNINGS
QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS
INCLUDEPATH += ../clangrefactoringbackend/source INCLUDEPATH += ../clangrefactoringbackend/source

View File

@@ -29,6 +29,8 @@
#include "modifiedtimecheckerinterface.h" #include "modifiedtimecheckerinterface.h"
#include "builddependencygeneratorinterface.h" #include "builddependencygeneratorinterface.h"
#include <sqlitetransaction.h>
#include <algorithm> #include <algorithm>
namespace ClangBackEnd { namespace ClangBackEnd {
@@ -51,19 +53,25 @@ OutputContainer setUnion(InputContainer1 &&input1,
return results; return results;
} }
BuildDependency BuildDependenciesProvider::create(const V2::ProjectPartContainer &projectPart) const BuildDependency BuildDependenciesProvider::create(const V2::ProjectPartContainer &projectPart)
{ {
SourceEntries includes = createSourceEntriesFromStorage(projectPart.sourcePathIds, SourceEntries includes = createSourceEntriesFromStorage(projectPart.sourcePathIds,
projectPart.projectPartId); projectPart.projectPartId);
if (!m_modifiedTimeChecker.isUpToDate(includes)) if (!m_modifiedTimeChecker.isUpToDate(includes)) {
return m_buildDependenciesGenerator.create(projectPart); BuildDependency buildDependency = m_generator.create(projectPart);
storeBuildDependency(buildDependency);
return buildDependency;
}
return createBuildDependencyFromStorage(std::move(includes)); return createBuildDependencyFromStorage(std::move(includes));
} }
BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage(SourceEntries &&includes) const BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage(
SourceEntries &&includes) const
{ {
BuildDependency buildDependency; BuildDependency buildDependency;
@@ -78,14 +86,18 @@ UsedMacros BuildDependenciesProvider::createUsedMacrosFromStorage(const SourceEn
UsedMacros usedMacros; UsedMacros usedMacros;
usedMacros.reserve(1024); usedMacros.reserve(1024);
Sqlite::DeferredTransaction transaction(m_transactionBackend);
for (const SourceEntry &entry : includes) { for (const SourceEntry &entry : includes) {
UsedMacros macros = m_buildDependenciesStorage.fetchUsedMacros(entry.sourceId); UsedMacros macros = m_storage.fetchUsedMacros(entry.sourceId);
std::sort(macros.begin(), macros.end()); std::sort(macros.begin(), macros.end());
usedMacros.insert(usedMacros.end(), usedMacros.insert(usedMacros.end(),
std::make_move_iterator(macros.begin()), std::make_move_iterator(macros.begin()),
std::make_move_iterator(macros.end())); std::make_move_iterator(macros.end()));
} }
transaction.commit();
return usedMacros; return usedMacros;
} }
@@ -94,15 +106,31 @@ SourceEntries BuildDependenciesProvider::createSourceEntriesFromStorage(
{ {
SourceEntries includes; SourceEntries includes;
Sqlite::DeferredTransaction transaction(m_transactionBackend);
for (FilePathId sourcePathId : sourcePathIds) { for (FilePathId sourcePathId : sourcePathIds) {
SourceEntries entries = m_buildDependenciesStorage.fetchDependSources(sourcePathId, SourceEntries entries = m_storage.fetchDependSources(sourcePathId,
projectPartId); projectPartId);
SourceEntries mergedEntries = setUnion<SourceEntries>(includes, entries); SourceEntries mergedEntries = setUnion<SourceEntries>(includes, entries);
includes = std::move(mergedEntries); includes = std::move(mergedEntries);
} }
transaction.commit();
return includes; return includes;
} }
void BuildDependenciesProvider::storeBuildDependency(const BuildDependency &buildDependency)
{
Sqlite::ImmediateTransaction transaction(m_transactionBackend);
m_storage.updateSources(buildDependency.includes);
m_storage.insertFileStatuses(buildDependency.fileStatuses);
m_storage.insertOrUpdateSourceDependencies(buildDependency.sourceDependencies);
m_storage.insertOrUpdateUsedMacros(buildDependency.usedMacros);
transaction.commit();
}
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -27,6 +27,10 @@
#include "builddependenciesproviderinterface.h" #include "builddependenciesproviderinterface.h"
namespace Sqlite {
class TransactionInterface;
}
namespace ClangBackEnd { namespace ClangBackEnd {
class BuildDependenciesStorageInterface; class BuildDependenciesStorageInterface;
@@ -38,25 +42,28 @@ class BuildDependenciesProvider : public BuildDependenciesProviderInterface
public: public:
BuildDependenciesProvider(BuildDependenciesStorageInterface &buildDependenciesStorage, BuildDependenciesProvider(BuildDependenciesStorageInterface &buildDependenciesStorage,
ModifiedTimeCheckerInterface &modifiedTimeChecker, ModifiedTimeCheckerInterface &modifiedTimeChecker,
BuildDependencyGeneratorInterface &buildDependenciesGenerator) BuildDependencyGeneratorInterface &buildDependenciesGenerator,
: m_buildDependenciesStorage(buildDependenciesStorage), Sqlite::TransactionInterface &transactionBackend)
m_modifiedTimeChecker(modifiedTimeChecker), : m_storage(buildDependenciesStorage)
m_buildDependenciesGenerator(buildDependenciesGenerator) , m_modifiedTimeChecker(modifiedTimeChecker)
{ , m_generator(buildDependenciesGenerator)
} , m_transactionBackend(transactionBackend)
{}
BuildDependency create(const V2::ProjectPartContainer &projectPart) const override; BuildDependency create(const V2::ProjectPartContainer &projectPart) override;
private: private:
BuildDependency createBuildDependencyFromStorage(SourceEntries &&includes) const; BuildDependency createBuildDependencyFromStorage(SourceEntries &&includes) const;
UsedMacros createUsedMacrosFromStorage(const SourceEntries &includes) const; UsedMacros createUsedMacrosFromStorage(const SourceEntries &includes) const;
SourceEntries createSourceEntriesFromStorage(const FilePathIds &sourcePathIds, SourceEntries createSourceEntriesFromStorage(const FilePathIds &sourcePathIds,
Utils::SmallStringView projectPartId) const; Utils::SmallStringView projectPartId) const;
void storeBuildDependency(const BuildDependency &buildDependency);
private: private:
BuildDependenciesStorageInterface &m_buildDependenciesStorage; BuildDependenciesStorageInterface &m_storage;
ModifiedTimeCheckerInterface &m_modifiedTimeChecker; ModifiedTimeCheckerInterface &m_modifiedTimeChecker;
BuildDependencyGeneratorInterface &m_buildDependenciesGenerator; BuildDependencyGeneratorInterface &m_generator;
Sqlite::TransactionInterface &m_transactionBackend;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -34,7 +34,7 @@ namespace ClangBackEnd {
class BuildDependenciesProviderInterface class BuildDependenciesProviderInterface
{ {
public: public:
virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) const = 0; virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) = 0;
protected: protected:
~BuildDependenciesProviderInterface() = default; ~BuildDependenciesProviderInterface() = default;

View File

@@ -47,25 +47,25 @@ class BuildDependenciesStorage final : public BuildDependenciesStorageInterface
using WriteStatement = typename Database::WriteStatement; using WriteStatement = typename Database::WriteStatement;
public: public:
BuildDependenciesStorage(Database &database) BuildDependenciesStorage(Database &database)
: m_transaction(database), : transaction(database),
m_database(database) database(database)
{ {
m_transaction.commit(); transaction.commit();
} }
void updateSources(const SourceEntries &sourceEntries) override void updateSources(const SourceEntries &sourceEntries) override
{ {
for (const SourceEntry &entry : sourceEntries) { for (const SourceEntry &entry : sourceEntries) {
m_updateBuildDependencyTimeStampStatement.write(static_cast<long long>(entry.lastModified), updateBuildDependencyTimeStampStatement.write(static_cast<long long>(entry.lastModified),
entry.sourceId.filePathId); entry.sourceId.filePathId);
m_updateSourceTypeStatement.write(static_cast<uchar>(entry.sourceType), updateSourceTypeStatement.write(static_cast<uchar>(entry.sourceType),
entry.sourceId.filePathId); entry.sourceId.filePathId);
} }
} }
void insertFileStatuses(const FileStatuses &fileStatuses) override void insertFileStatuses(const FileStatuses &fileStatuses) override
{ {
WriteStatement &statement = m_insertFileStatusesStatement; WriteStatement &statement = insertFileStatusesStatement;
for (const FileStatus &fileStatus : fileStatuses) for (const FileStatus &fileStatus : fileStatuses)
statement.write(fileStatus.filePathId.filePathId, statement.write(fileStatus.filePathId.filePathId,
@@ -76,41 +76,41 @@ public:
long long fetchLowestLastModifiedTime(FilePathId sourceId) const override long long fetchLowestLastModifiedTime(FilePathId sourceId) const override
{ {
ReadStatement &statement = m_getLowestLastModifiedTimeOfDependencies; ReadStatement &statement = getLowestLastModifiedTimeOfDependencies;
return statement.template value<long long>(sourceId.filePathId).value_or(0); return statement.template value<long long>(sourceId.filePathId).value_or(0);
} }
void insertOrUpdateUsedMacros(const UsedMacros &usedMacros) override void insertOrUpdateUsedMacros(const UsedMacros &usedMacros) override
{ {
WriteStatement &insertStatement = m_insertIntoNewUsedMacrosStatement; WriteStatement &insertStatement = insertIntoNewUsedMacrosStatement;
for (const UsedMacro &usedMacro : usedMacros) for (const UsedMacro &usedMacro : usedMacros)
insertStatement.write(usedMacro.filePathId.filePathId, usedMacro.macroName); insertStatement.write(usedMacro.filePathId.filePathId, usedMacro.macroName);
m_syncNewUsedMacrosStatement.execute(); syncNewUsedMacrosStatement.execute();
m_deleteOutdatedUsedMacrosStatement.execute(); deleteOutdatedUsedMacrosStatement.execute();
m_deleteNewUsedMacrosTableStatement.execute(); deleteNewUsedMacrosTableStatement.execute();
} }
void insertOrUpdateSourceDependencies(const SourceDependencies &sourceDependencies) override void insertOrUpdateSourceDependencies(const SourceDependencies &sourceDependencies) override
{ {
WriteStatement &insertStatement = m_insertIntoNewSourceDependenciesStatement; WriteStatement &insertStatement = insertIntoNewSourceDependenciesStatement;
for (SourceDependency sourceDependency : sourceDependencies) for (SourceDependency sourceDependency : sourceDependencies)
insertStatement.write(sourceDependency.filePathId.filePathId, insertStatement.write(sourceDependency.filePathId.filePathId,
sourceDependency.dependencyFilePathId.filePathId); sourceDependency.dependencyFilePathId.filePathId);
m_syncNewSourceDependenciesStatement.execute(); syncNewSourceDependenciesStatement.execute();
m_deleteOutdatedSourceDependenciesStatement.execute(); deleteOutdatedSourceDependenciesStatement.execute();
m_deleteNewSourceDependenciesStatement.execute(); deleteNewSourceDependenciesStatement.execute();
} }
SourceEntries fetchDependSources(FilePathId sourceId, SourceEntries fetchDependSources(FilePathId sourceId,
Utils::SmallStringView projectPartName) const override Utils::SmallStringView projectPartName) const override
{ {
auto projectPartId = m_fetchProjectPartIdStatement.template value<int>(projectPartName); auto projectPartId = fetchProjectPartIdStatement.template value<int>(projectPartName);
if (projectPartId) { if (projectPartId) {
return m_fetchSourceDependenciesStatement.template values<SourceEntry, 3>( return fetchSourceDependenciesStatement.template values<SourceEntry, 3>(
300, 300,
sourceId.filePathId, sourceId.filePathId,
projectPartId.value()); projectPartId.value());
@@ -120,7 +120,7 @@ public:
UsedMacros fetchUsedMacros(FilePathId sourceId) const override UsedMacros fetchUsedMacros(FilePathId sourceId) const override
{ {
return m_fetchUsedMacrosStatement.template values<UsedMacro, 2>(128, sourceId.filePathId); return fetchUsedMacrosStatement.template values<UsedMacro, 2>(128, sourceId.filePathId);
} }
static Utils::SmallString toJson(const Utils::SmallStringVector &strings) static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
@@ -159,7 +159,7 @@ public:
const Sqlite::Column &macroNameColumn = table.addColumn("macroName", Sqlite::ColumnType::Text); const Sqlite::Column &macroNameColumn = table.addColumn("macroName", Sqlite::ColumnType::Text);
table.addIndex({sourceIdColumn, macroNameColumn}); table.addIndex({sourceIdColumn, macroNameColumn});
table.initialize(m_database); table.initialize(database);
return table; return table;
} }
@@ -173,75 +173,75 @@ public:
const Sqlite::Column &dependencySourceIdColumn = table.addColumn("dependencySourceId", Sqlite::ColumnType::Text); const Sqlite::Column &dependencySourceIdColumn = table.addColumn("dependencySourceId", Sqlite::ColumnType::Text);
table.addIndex({sourceIdColumn, dependencySourceIdColumn}); table.addIndex({sourceIdColumn, dependencySourceIdColumn});
table.initialize(m_database); table.initialize(database);
return table; return table;
} }
public: public:
Sqlite::ImmediateNonThrowingDestructorTransaction m_transaction; Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
Database &m_database; Database &database;
Sqlite::Table newUsedMacroTable{createNewUsedMacrosTable()}; Sqlite::Table newUsedMacroTable{createNewUsedMacrosTable()};
Sqlite::Table newNewSourceDependenciesTable{createNewSourceDependenciesTable()}; Sqlite::Table newNewSourceDependenciesTable{createNewSourceDependenciesTable()};
WriteStatement m_insertIntoNewUsedMacrosStatement{ WriteStatement insertIntoNewUsedMacrosStatement{
"INSERT INTO newUsedMacros(sourceId, macroName) VALUES (?,?)", "INSERT INTO newUsedMacros(sourceId, macroName) VALUES (?,?)",
m_database database
}; };
WriteStatement m_syncNewUsedMacrosStatement{ WriteStatement syncNewUsedMacrosStatement{
"INSERT INTO usedMacros(sourceId, macroName) SELECT sourceId, macroName FROM newUsedMacros WHERE NOT EXISTS (SELECT sourceId FROM usedMacros WHERE usedMacros.sourceId == newUsedMacros.sourceId AND usedMacros.macroName == newUsedMacros.macroName)", "INSERT INTO usedMacros(sourceId, macroName) SELECT sourceId, macroName FROM newUsedMacros WHERE NOT EXISTS (SELECT sourceId FROM usedMacros WHERE usedMacros.sourceId == newUsedMacros.sourceId AND usedMacros.macroName == newUsedMacros.macroName)",
m_database database
}; };
WriteStatement m_deleteOutdatedUsedMacrosStatement{ WriteStatement deleteOutdatedUsedMacrosStatement{
"DELETE FROM usedMacros WHERE sourceId IN (SELECT sourceId FROM newUsedMacros) AND NOT EXISTS (SELECT sourceId FROM newUsedMacros WHERE newUsedMacros.sourceId == usedMacros.sourceId AND newUsedMacros.macroName == usedMacros.macroName)", "DELETE FROM usedMacros WHERE sourceId IN (SELECT sourceId FROM newUsedMacros) AND NOT EXISTS (SELECT sourceId FROM newUsedMacros WHERE newUsedMacros.sourceId == usedMacros.sourceId AND newUsedMacros.macroName == usedMacros.macroName)",
m_database database
}; };
WriteStatement m_deleteNewUsedMacrosTableStatement{ WriteStatement deleteNewUsedMacrosTableStatement{
"DELETE FROM newUsedMacros", "DELETE FROM newUsedMacros",
m_database database
}; };
mutable ReadStatement m_getLowestLastModifiedTimeOfDependencies{ mutable ReadStatement getLowestLastModifiedTimeOfDependencies{
"WITH RECURSIVE sourceIds(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, sourceIds WHERE sourceDependencies.sourceId = sourceIds.sourceId) SELECT min(lastModified) FROM fileStatuses, sourceIds WHERE fileStatuses.sourceId = sourceIds.sourceId", "WITH RECURSIVE sourceIds(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, sourceIds WHERE sourceDependencies.sourceId = sourceIds.sourceId) SELECT min(lastModified) FROM fileStatuses, sourceIds WHERE fileStatuses.sourceId = sourceIds.sourceId",
m_database database
}; };
WriteStatement m_insertIntoNewSourceDependenciesStatement{ WriteStatement insertIntoNewSourceDependenciesStatement{
"INSERT INTO newSourceDependencies(sourceId, dependencySourceId) VALUES (?,?)", "INSERT INTO newSourceDependencies(sourceId, dependencySourceId) VALUES (?,?)",
m_database database
}; };
WriteStatement m_insertFileStatusesStatement{ WriteStatement insertFileStatusesStatement{
"INSERT OR REPLACE INTO fileStatuses(sourceId, size, lastModified, isInPrecompiledHeader) VALUES (?,?,?,?)", "INSERT OR REPLACE INTO fileStatuses(sourceId, size, lastModified, isInPrecompiledHeader) VALUES (?,?,?,?)",
m_database database
}; };
WriteStatement m_syncNewSourceDependenciesStatement{ WriteStatement syncNewSourceDependenciesStatement{
"INSERT INTO sourceDependencies(sourceId, dependencySourceId) SELECT sourceId, dependencySourceId FROM newSourceDependencies WHERE NOT EXISTS (SELECT sourceId FROM sourceDependencies WHERE sourceDependencies.sourceId == newSourceDependencies.sourceId AND sourceDependencies.dependencySourceId == newSourceDependencies.dependencySourceId)", "INSERT INTO sourceDependencies(sourceId, dependencySourceId) SELECT sourceId, dependencySourceId FROM newSourceDependencies WHERE NOT EXISTS (SELECT sourceId FROM sourceDependencies WHERE sourceDependencies.sourceId == newSourceDependencies.sourceId AND sourceDependencies.dependencySourceId == newSourceDependencies.dependencySourceId)",
m_database database
}; };
WriteStatement m_deleteOutdatedSourceDependenciesStatement{ WriteStatement deleteOutdatedSourceDependenciesStatement{
"DELETE FROM sourceDependencies WHERE sourceId IN (SELECT sourceId FROM newSourceDependencies) AND NOT EXISTS (SELECT sourceId FROM newSourceDependencies WHERE newSourceDependencies.sourceId == sourceDependencies.sourceId AND newSourceDependencies.dependencySourceId == sourceDependencies.dependencySourceId)", "DELETE FROM sourceDependencies WHERE sourceId IN (SELECT sourceId FROM newSourceDependencies) AND NOT EXISTS (SELECT sourceId FROM newSourceDependencies WHERE newSourceDependencies.sourceId == sourceDependencies.sourceId AND newSourceDependencies.dependencySourceId == sourceDependencies.dependencySourceId)",
m_database database
}; };
WriteStatement m_deleteNewSourceDependenciesStatement{ WriteStatement deleteNewSourceDependenciesStatement{
"DELETE FROM newSourceDependencies", "DELETE FROM newSourceDependencies",
m_database database
}; };
WriteStatement m_updateBuildDependencyTimeStampStatement{ WriteStatement updateBuildDependencyTimeStampStatement{
"UPDATE fileStatuses SET buildDependencyTimeStamp = ? WHERE sourceId == ?", "UPDATE fileStatuses SET buildDependencyTimeStamp = ? WHERE sourceId == ?",
m_database database
}; };
WriteStatement m_updateSourceTypeStatement{ WriteStatement updateSourceTypeStatement{
"UPDATE projectPartsSources SET sourceType = ? WHERE sourceId == ?", "UPDATE projectPartsSources SET sourceType = ? WHERE sourceId == ?",
m_database database
}; };
mutable ReadStatement m_fetchSourceDependenciesStatement{ mutable ReadStatement fetchSourceDependenciesStatement{
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, collectedDependencies WHERE sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT sourceId, buildDependencyTimeStamp, sourceType FROM collectedDependencies NATURAL JOIN projectPartsSources NATURAL JOIN fileStatuses WHERE projectPartId = ?", "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, collectedDependencies WHERE sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT sourceId, buildDependencyTimeStamp, sourceType FROM collectedDependencies NATURAL JOIN projectPartsSources NATURAL JOIN fileStatuses WHERE projectPartId = ?",
m_database database
}; };
mutable ReadStatement m_fetchProjectPartIdStatement{ mutable ReadStatement fetchProjectPartIdStatement{
"SELECT projectPartId FROM projectParts WHERE projectPartName = ?", "SELECT projectPartId FROM projectParts WHERE projectPartName = ?",
m_database database
}; };
mutable ReadStatement m_fetchUsedMacrosStatement{ mutable ReadStatement fetchUsedMacrosStatement{
"SELECT macroName, sourceId FROM usedMacros WHERE sourceId = ?", "SELECT macroName, sourceId FROM usedMacros WHERE sourceId = ?",
m_database database
}; };
}; };
} }

View File

@@ -1,12 +1,11 @@
INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD
SOURCES += \ SOURCES += \
$$PWD/builddependenciesprovider.cpp \
$$PWD/pchmanagerserver.cpp \ $$PWD/pchmanagerserver.cpp \
$$PWD/projectparts.cpp \ $$PWD/projectparts.cpp \
$$PWD/projectpartqueue.cpp \ $$PWD/projectpartqueue.cpp \
$$PWD/pchtaskgenerator.cpp \ $$PWD/pchtaskgenerator.cpp
$$PWD/builddependenciesprovider.cpp \
$$PWD/builddependencycollector.cpp
HEADERS += \ HEADERS += \
$$PWD/pchmanagerserver.h \ $$PWD/pchmanagerserver.h \
@@ -34,16 +33,13 @@ HEADERS += \
$$PWD/modifiedtimecheckerinterface.h \ $$PWD/modifiedtimecheckerinterface.h \
$$PWD/sourceentry.h \ $$PWD/sourceentry.h \
$$PWD/builddependenciesstorage.h \ $$PWD/builddependenciesstorage.h \
$$PWD/builddependencycollector.h \ $$PWD/builddependencygeneratorinterface.h
$$PWD/builddependencygeneratorinterface.h \
$$PWD/collectbuilddependencytoolaction.h \
$$PWD/collectbuilddependencyaction.h \
$$PWD/collectbuilddependencypreprocessorcallbacks.h
!isEmpty(LIBTOOLING_LIBS) { !isEmpty(LIBTOOLING_LIBS) {
SOURCES += \ SOURCES += \
$$PWD/usedmacrosandsourcescollector.cpp \ $$PWD/usedmacrosandsourcescollector.cpp \
$$PWD/pchcreator.cpp $$PWD/pchcreator.cpp \
$$PWD/builddependencycollector.cpp
HEADERS += \ HEADERS += \
$$PWD/collectusedmacroactionfactory.h \ $$PWD/collectusedmacroactionfactory.h \
@@ -51,5 +47,9 @@ HEADERS += \
$$PWD/collectusedmacrosandsourcespreprocessorcallbacks.h \ $$PWD/collectusedmacrosandsourcespreprocessorcallbacks.h \
$$PWD/pchcreator.h \ $$PWD/pchcreator.h \
$$PWD/processormanager.h \ $$PWD/processormanager.h \
$$PWD/usedmacrosandsourcescollector.h $$PWD/usedmacrosandsourcescollector.h \
$$PWD/builddependencycollector.h \
$$PWD/collectbuilddependencytoolaction.h \
$$PWD/collectbuilddependencyaction.h \
$$PWD/collectbuilddependencypreprocessorcallbacks.h
} }

View File

@@ -44,7 +44,8 @@
namespace ClangBackEnd { namespace ClangBackEnd {
class CollectBuildDependencyPreprocessorCallbacks final : public clang::PPCallbacks, class CollectBuildDependencyPreprocessorCallbacks final
: public clang::PPCallbacks,
public CollectUsedMacrosAndSourcesPreprocessorCallbacksBase public CollectUsedMacrosAndSourcesPreprocessorCallbacksBase
{ {
public: public:

View File

@@ -19,7 +19,8 @@ LIBS += $$LIBTOOLING_LIBS
INCLUDEPATH += $$LLVM_INCLUDEPATH INCLUDEPATH += $$LLVM_INCLUDEPATH
INCLUDEPATH += ../clangpchmanagerbackend/source INCLUDEPATH += ../clangpchmanagerbackend/source
QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS QMAKE_CXXFLAGS_WARN_ON *= $$LLVM_CXXFLAGS_WARNINGS
QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS
SOURCES += \ SOURCES += \
clangrefactoringbackendmain.cpp clangrefactoringbackendmain.cpp

View File

@@ -8228,6 +8228,8 @@ static void checkNode(QmlJS::SimpleReaderNode::Ptr node, TestRewriterView *view)
void tst_TestCore::writeAnnotations() void tst_TestCore::writeAnnotations()
{ {
QSKIP("We have to improve handling of emtpy lines.", SkipAll);
const QLatin1String qmlCode("\n" const QLatin1String qmlCode("\n"
"import QtQuick 2.1\n" "import QtQuick 2.1\n"
"\n" "\n"

View File

@@ -223,8 +223,9 @@ void tst_FileFormat::testLibraryPaths()
project->setSourceDirectory(testDataDir); project->setSourceDirectory(testDataDir);
QStringList expectedPaths(QStringList() << SRCDIR "/otherLibrary" const QDir base(testDataDir);
<< SRCDIR "/data/library"); const QStringList expectedPaths({base.relativeFilePath(SRCDIR "/otherLibrary"),
base.relativeFilePath(SRCDIR "/data/library")});
qDebug() << expectedPaths << project->importPaths(); qDebug() << expectedPaths << project->importPaths();
QCOMPARE(project->importPaths().toSet(), expectedPaths.toSet()); QCOMPARE(project->importPaths().toSet(), expectedPaths.toSet());
delete project; delete project;

View File

@@ -93,10 +93,18 @@ void tst_Reformatter::test()
// compare line by line // compare line by line
int commonLines = qMin(newLines.size(), sourceLines.size()); int commonLines = qMin(newLines.size(), sourceLines.size());
bool insideMultiLineComment = false;
for (int i = 0; i < commonLines; ++i) { for (int i = 0; i < commonLines; ++i) {
// names intentional to make 'Actual (sourceLine): ...\nExpected (newLinee): ...' line up // names intentional to make 'Actual (sourceLine): ...\nExpected (newLinee): ...' line up
const QString &sourceLine = sourceLines.at(i); const QString &sourceLine = sourceLines.at(i);
const QString &newLinee = newLines.at(i); const QString &newLinee = newLines.at(i);
if (!insideMultiLineComment && sourceLine.trimmed().startsWith("/*")) {
insideMultiLineComment = true;
sourceLines.insert(i, "\n");
continue;
}
if (sourceLine.trimmed().endsWith("*/"))
insideMultiLineComment = false;
if (sourceLine.trimmed().isEmpty() && newLinee.trimmed().isEmpty()) if (sourceLine.trimmed().isEmpty() && newLinee.trimmed().isEmpty())
continue; continue;
bool fail = !QCOMPARE_NOEXIT(newLinee, sourceLine); bool fail = !QCOMPARE_NOEXIT(newLinee, sourceLine);

View File

@@ -656,7 +656,11 @@ void extremeFunction(
++uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunbelievableLongValue; ++uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunbelievableLongValue;
extremeFunction( extremeFunction(
"some super duper super duper super duper super duper super duper super duper super duper long"); "some super duper super duper super duper super duper super duper super duper long");
// BreakStringLiterals splits the string.
extremeFunction("some super duper super duper super duper super duper super duper super duper "
"super duper long");
} }
void extremeFunction2(int parameter1, void extremeFunction2(int parameter1,

View File

@@ -28,6 +28,7 @@
#include "mockbuilddependenciesstorage.h" #include "mockbuilddependenciesstorage.h"
#include "mockmodifiedtimechecker.h" #include "mockmodifiedtimechecker.h"
#include "mockbuilddependencygenerator.h" #include "mockbuilddependencygenerator.h"
#include "mocksqlitetransactionbackend.h"
#include <builddependenciesprovider.h> #include <builddependenciesprovider.h>
@@ -54,10 +55,14 @@ MATCHER_P(HasSourceId, sourceId, std::string(negation ? "hasn't" : "has")
class BuildDependenciesProvider : public testing::Test class BuildDependenciesProvider : public testing::Test
{ {
protected: protected:
NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend;
NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage; NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage;
NiceMock<MockModifiedTimeChecker> mockModifiedTimeChecker; NiceMock<MockModifiedTimeChecker> mockModifiedTimeChecker;
NiceMock<MockBuildDependencyGenerator> mockBuildDependenciesGenerator; NiceMock<MockBuildDependencyGenerator> mockBuildDependenciesGenerator;
ClangBackEnd::BuildDependenciesProvider provider{mockBuildDependenciesStorage, mockModifiedTimeChecker, mockBuildDependenciesGenerator}; ClangBackEnd::BuildDependenciesProvider provider{mockBuildDependenciesStorage,
mockModifiedTimeChecker,
mockBuildDependenciesGenerator,
mockSqliteTransactionBackend};
ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1", ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
{"--yi"}, {"--yi"},
{{"YI", "1"}}, {{"YI", "1"}},
@@ -70,22 +75,47 @@ protected:
{"/er"}, {"/er"},
{1}, {1},
{2, 3, 4}}; {2, 3, 4}};
SourceEntries firstSources{{1, SourceType::UserInclude, 1}, {2, SourceType::UserInclude, 1}, {10, SourceType::UserInclude, 1}}; SourceEntries firstSources{{1, SourceType::UserInclude, 1},
SourceEntries secondSources{{1, SourceType::UserInclude, 1}, {3, SourceType::UserInclude, 1}, {8, SourceType::UserInclude, 1}}; {2, SourceType::UserInclude, 1},
SourceEntries thirdSources{{4, SourceType::UserInclude, 1}, {8, SourceType::UserInclude, 1}, {10, SourceType::UserInclude, 1}}; {10, SourceType::UserInclude, 1}};
SourceEntries secondSources{{1, SourceType::UserInclude, 1},
{3, SourceType::UserInclude, 1},
{8, SourceType::UserInclude, 1}};
SourceEntries thirdSources{{4, SourceType::UserInclude, 1},
{8, SourceType::UserInclude, 1},
{10, SourceType::UserInclude, 1}};
UsedMacros firstUsedMacros{{"YI", 1}}; UsedMacros firstUsedMacros{{"YI", 1}};
UsedMacros secondUsedMacros{{"LIANG", 2}, {"ER", 2}}; UsedMacros secondUsedMacros{{"LIANG", 2}, {"ER", 2}};
UsedMacros thirdUsedMacros{{"SAN", 10}}; UsedMacros thirdUsedMacros{{"SAN", 10}};
BuildDependency buildDependency{secondSources, {}}; FilePathIds sourceFiles{1, 3, 8};
ClangBackEnd::SourceDependencies sourceDependencies{{1, 3}, {1, 8}};
ClangBackEnd::FileStatuses fileStatuses{{1, 21, 12, false},
{3, 21, 12, false},
{8, 21, 12, false}};
BuildDependency buildDependency{
secondSources,
secondUsedMacros,
sourceFiles,
sourceDependencies,
fileStatuses
};
}; };
TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromStorageIfTimeStampsAreUpToDate) TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromStorageIfTimeStampsAreUpToDate)
{ {
InSequence s; InSequence s;
EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillRepeatedly(Return(firstSources)); EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockBuildDependenciesStorage,
fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1")))
.WillRepeatedly(Return(firstSources));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true)); EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true));
EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)).Times(0); EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockSqliteTransactionBackend, commit());
provider.create(projectPart1); provider.create(projectPart1);
} }
@@ -95,6 +125,7 @@ TEST_F(BuildDependenciesProvider, FetchDependSourcesFromStorage)
ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(firstSources)); ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(firstSources));
ON_CALL(mockBuildDependenciesStorage, fetchDependSources({3}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(secondSources)); ON_CALL(mockBuildDependenciesStorage, fetchDependSources({3}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(secondSources));
ON_CALL(mockBuildDependenciesStorage, fetchDependSources({4}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(thirdSources)); ON_CALL(mockBuildDependenciesStorage, fetchDependSources({4}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(thirdSources));
ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(true)); ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(true));
auto buildDependency = provider.create(projectPart2); auto buildDependency = provider.create(projectPart2);
@@ -106,9 +137,20 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromGeneratorIfTi
{ {
InSequence s; InSequence s;
EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillRepeatedly(Return(firstSources)); EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockBuildDependenciesStorage,
fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1")))
.WillRepeatedly(Return(firstSources));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(false)); EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(false));
EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)); EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1))
.WillOnce(Return(buildDependency));
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockBuildDependenciesStorage, updateSources(Eq(secondSources)));
EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatuses)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(secondUsedMacros)));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
provider.create(projectPart1); provider.create(projectPart1);
} }
@@ -128,11 +170,15 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchUsedMacrosFromStorageIfTimeSta
{ {
InSequence s; InSequence s;
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillRepeatedly(Return(firstSources)); EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillRepeatedly(Return(firstSources));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true)); EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true));
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({1})); EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({1}));
EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({2})); EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({2}));
EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({10})); EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({10}));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
provider.create(projectPart1); provider.create(projectPart1);
} }

View File

@@ -51,21 +51,21 @@ class BuildDependenciesStorage : public testing::Test
protected: protected:
NiceMock<MockSqliteDatabase> mockDatabase; NiceMock<MockSqliteDatabase> mockDatabase;
Storage storage{mockDatabase}; Storage storage{mockDatabase};
MockSqliteWriteStatement &insertIntoNewUsedMacrosStatement = storage.m_insertIntoNewUsedMacrosStatement; MockSqliteWriteStatement &insertIntoNewUsedMacrosStatement = storage.insertIntoNewUsedMacrosStatement;
MockSqliteWriteStatement &syncNewUsedMacrosStatement =storage.m_syncNewUsedMacrosStatement; MockSqliteWriteStatement &syncNewUsedMacrosStatement =storage.syncNewUsedMacrosStatement;
MockSqliteWriteStatement &deleteOutdatedUsedMacrosStatement = storage.m_deleteOutdatedUsedMacrosStatement; MockSqliteWriteStatement &deleteOutdatedUsedMacrosStatement = storage.deleteOutdatedUsedMacrosStatement;
MockSqliteWriteStatement &deleteNewUsedMacrosTableStatement = storage.m_deleteNewUsedMacrosTableStatement; MockSqliteWriteStatement &deleteNewUsedMacrosTableStatement = storage.deleteNewUsedMacrosTableStatement;
MockSqliteWriteStatement &insertFileStatuses = storage.m_insertFileStatusesStatement; MockSqliteWriteStatement &insertFileStatuses = storage.insertFileStatusesStatement;
MockSqliteWriteStatement &insertIntoNewSourceDependenciesStatement = storage.m_insertIntoNewSourceDependenciesStatement; MockSqliteWriteStatement &insertIntoNewSourceDependenciesStatement = storage.insertIntoNewSourceDependenciesStatement;
MockSqliteWriteStatement &syncNewSourceDependenciesStatement = storage.m_syncNewSourceDependenciesStatement; MockSqliteWriteStatement &syncNewSourceDependenciesStatement = storage.syncNewSourceDependenciesStatement;
MockSqliteWriteStatement &deleteOutdatedSourceDependenciesStatement = storage.m_deleteOutdatedSourceDependenciesStatement; MockSqliteWriteStatement &deleteOutdatedSourceDependenciesStatement = storage.deleteOutdatedSourceDependenciesStatement;
MockSqliteWriteStatement &deleteNewSourceDependenciesStatement = storage.m_deleteNewSourceDependenciesStatement; MockSqliteWriteStatement &deleteNewSourceDependenciesStatement = storage.deleteNewSourceDependenciesStatement;
MockSqliteReadStatement &getLowestLastModifiedTimeOfDependencies = storage.m_getLowestLastModifiedTimeOfDependencies; MockSqliteReadStatement &getLowestLastModifiedTimeOfDependencies = storage.getLowestLastModifiedTimeOfDependencies;
MockSqliteWriteStatement &updateBuildDependencyTimeStampStatement = storage.m_updateBuildDependencyTimeStampStatement; MockSqliteWriteStatement &updateBuildDependencyTimeStampStatement = storage.updateBuildDependencyTimeStampStatement;
MockSqliteWriteStatement &updateSourceTypeStatement = storage.m_updateSourceTypeStatement; MockSqliteWriteStatement &updateSourceTypeStatement = storage.updateSourceTypeStatement;
MockSqliteReadStatement &fetchSourceDependenciesStatement = storage.m_fetchSourceDependenciesStatement; MockSqliteReadStatement &fetchSourceDependenciesStatement = storage.fetchSourceDependenciesStatement;
MockSqliteReadStatement &fetchProjectPartIdStatement = storage.m_fetchProjectPartIdStatement; MockSqliteReadStatement &fetchProjectPartIdStatement = storage.fetchProjectPartIdStatement;
MockSqliteReadStatement &fetchUsedMacrosStatement = storage.m_fetchUsedMacrosStatement; MockSqliteReadStatement &fetchUsedMacrosStatement = storage.fetchUsedMacrosStatement;
}; };
TEST_F(BuildDependenciesStorage, ConvertStringsToJson) TEST_F(BuildDependenciesStorage, ConvertStringsToJson)

View File

@@ -22,6 +22,7 @@ include(../../../src/shared/clang/clang_defines.pri)
!contains(QMAKE_DEFAULT_LIBDIRS, $$LLVM_LIBDIR): QMAKE_RPATHDIR += $$LLVM_LIBDIR !contains(QMAKE_DEFAULT_LIBDIRS, $$LLVM_LIBDIR): QMAKE_RPATHDIR += $$LLVM_LIBDIR
LLVM_CXXFLAGS ~= s,-g\d?, LLVM_CXXFLAGS ~= s,-g\d?,
QMAKE_CXXFLAGS_WARN_ON *= $$LLVM_CXXFLAGS_WARNINGS
QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS
DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($$LLVM_BINDIR/clang)xxx\\\"\" DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($$LLVM_BINDIR/clang)xxx\\\"\"

View File

@@ -312,6 +312,14 @@ TEST_F(ClangCompletionContextAnalyzer, AfterOpeningParenthesis)
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClang, 0, 0, positionInText, true)); ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClang, 0, 0, positionInText, true));
} }
TEST_F(ClangCompletionContextAnalyzer, AfterOpeningBraceAndIdentifierOnNewLine)
{
auto analyzer = runAnalyzer("if (1) {\n"
"cla@");
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClang, -3, -3, positionInText, true));
}
TEST_F(ClangCompletionContextAnalyzer, ArgumentOneAtSignal) TEST_F(ClangCompletionContextAnalyzer, ArgumentOneAtSignal)
{ {
auto analyzer = runAnalyzer("SIGNAL(@"); auto analyzer = runAnalyzer("SIGNAL(@");

View File

@@ -230,6 +230,84 @@ TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderLinux)
"-isystem", QDir::toNativeSeparators("/usr/include"))); "-isystem", QDir::toNativeSeparators("/usr/include")));
} }
TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderNoVersion)
{
projectPart.headerPaths = {HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include", HeaderPathType::BuiltIn},
HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++", HeaderPathType::BuiltIn},
HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\i686-w64-mingw32", HeaderPathType::BuiltIn},
HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\backward", HeaderPathType::BuiltIn}
};
projectPart.toolChainTargetTriple = "x86_64-w64-windows-gnu";
CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
CppTools::UseSystemHeader::No,
CppTools::SkipBuiltIn::No,
CppTools::SkipLanguageDefines::Yes,
"7.0.0",
"");
compilerOptionsBuilder.addHeaderPathOptions();
ASSERT_THAT(compilerOptionsBuilder.options(),
ElementsAre("-nostdinc",
"-nostdlibinc",
"-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include"),
"-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++"),
"-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\i686-w64-mingw32"),
"-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\backward"),
"-isystem", QDir::toNativeSeparators(CLANG_RESOURCE_DIR "")));
}
TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderAndroidClang)
{
projectPart.headerPaths = {
HeaderPath{
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include\\i686-linux-android",
HeaderPathType::BuiltIn},
HeaderPath{
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++\\include",
HeaderPathType::BuiltIn},
HeaderPath{
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\android\\support\\include",
HeaderPathType::BuiltIn},
HeaderPath{
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++abi\\include",
HeaderPathType::BuiltIn},
HeaderPath{"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include",
HeaderPathType::BuiltIn}};
projectPart.toolChainTargetTriple = "i686-linux-android";
CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
CppTools::UseSystemHeader::No,
CppTools::SkipBuiltIn::No,
CppTools::SkipLanguageDefines::Yes,
"7.0.0",
"");
compilerOptionsBuilder.addHeaderPathOptions();
ASSERT_THAT(
compilerOptionsBuilder.options(),
ElementsAre(
"-nostdinc",
"-nostdlibinc",
"-isystem",
QDir::toNativeSeparators(
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include\\i686-linux-android"),
"-isystem",
QDir::toNativeSeparators(
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++\\include"),
"-isystem",
QDir::toNativeSeparators(
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\android\\support\\include"),
"-isystem",
QDir::toNativeSeparators(
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++abi\\include"),
"-isystem",
QDir::toNativeSeparators(CLANG_RESOURCE_DIR ""),
"-isystem",
QDir::toNativeSeparators(
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include")));
}
TEST_F(CompilerOptionsBuilder, NoPrecompiledHeader) TEST_F(CompilerOptionsBuilder, NoPrecompiledHeader)
{ {
compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::CompilerOptionsBuilder::PchUsage::None); compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::CompilerOptionsBuilder::PchUsage::None);

View File

@@ -592,9 +592,9 @@ class WithVirtualFunctionDefined {
namespace NFoo { namespace NBar { namespace NTest { class NamespaceTypeSpelling; } } } namespace NFoo { namespace NBar { namespace NTest { class NamespaceTypeSpelling; } } }
Undeclared u; Undeclared u;
#define Q_PROPERTY(arg) static_assert("Q_PROPERTY", #arg); // Keep these in sync with wrappedQtHeaders/QtCore/qobjectdefs.h
#include "../../../../share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h" #define SIGNAL(arg) #arg
#define SLOT(arg) #arg
class Property { class Property {
Q_PROPERTY(const volatile unsigned long long * prop READ getProp WRITE setProp NOTIFY propChanged) Q_PROPERTY(const volatile unsigned long long * prop READ getProp WRITE setProp NOTIFY propChanged)
Q_PROPERTY(const QString str READ getStr) Q_PROPERTY(const QString str READ getStr)
@@ -674,3 +674,15 @@ int signalSlotTest() {
SIGNAL(something(QString (*func1)(QString))); SIGNAL(something(QString (*func1)(QString)));
1 == 2; 1 == 2;
} }
class NonConstParameterConstructor
{
NonConstParameterConstructor() = default;
NonConstParameterConstructor(NonConstParameterConstructor &buildDependenciesStorage);
void Call()
{
NonConstParameterConstructor foo;
NonConstParameterConstructor bar(foo);
}
};

View File

@@ -32,6 +32,7 @@
class MockBuildDependenciesProvider : public ClangBackEnd::BuildDependenciesProviderInterface class MockBuildDependenciesProvider : public ClangBackEnd::BuildDependenciesProviderInterface
{ {
public: public:
MOCK_CONST_METHOD1(create, MOCK_METHOD1(
create,
ClangBackEnd::BuildDependency(const ClangBackEnd::V2::ProjectPartContainer &projectPart)); ClangBackEnd::BuildDependency(const ClangBackEnd::V2::ProjectPartContainer &projectPart));
}; };

View File

@@ -1679,6 +1679,24 @@ TEST_F(TokenProcessor, QtOldStyleSignalFunctionPointerType)
ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::Type));
} }
TEST_F(TokenProcessor, NonConstParameterConstructor)
{
const auto infos = translationUnit.tokenInfosInRange(sourceRange(681, 90));
infos[1];
ASSERT_THAT(infos[4], Not(HasMixin(HighlightingType::OutputArgument)));
}
TEST_F(TokenProcessor, DISABLED_NonConstArgumentConstructor)
{
const auto infos = translationUnit.tokenInfosInRange(sourceRange(686, 47));
infos[2];
ASSERT_THAT(infos[3], HasMixin(HighlightingType::OutputArgument));
}
Data *TokenProcessor::d; Data *TokenProcessor::d;
void TokenProcessor::SetUpTestCase() void TokenProcessor::SetUpTestCase()

View File

@@ -107,8 +107,7 @@ SOURCES += \
pchtaskgenerator-test.cpp \ pchtaskgenerator-test.cpp \
compilationdatabaseutils-test.cpp \ compilationdatabaseutils-test.cpp \
builddependenciesprovider-test.cpp \ builddependenciesprovider-test.cpp \
builddependenciesstorage-test.cpp \ builddependenciesstorage-test.cpp
builddependencycollector-test.cpp
!isEmpty(LIBCLANG_LIBS) { !isEmpty(LIBCLANG_LIBS) {
SOURCES += \ SOURCES += \
@@ -185,7 +184,8 @@ SOURCES += \
symbolscollector-test.cpp \ symbolscollector-test.cpp \
symbolfinder-test.cpp \ symbolfinder-test.cpp \
testclangtool.cpp \ testclangtool.cpp \
usedmacrocollector-test.cpp usedmacrocollector-test.cpp \
builddependencycollector-test.cpp
} }
exists($$GOOGLEBENCHMARK_DIR) { exists($$GOOGLEBENCHMARK_DIR) {