forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.8'
Change-Id: Ife02e25f89a601e066851cddf0e000ac9491fc35
This commit is contained in:
@@ -203,6 +203,8 @@ 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)
|
||||||
{
|
{
|
||||||
|
@@ -2948,7 +2948,10 @@ class DumperBase:
|
|||||||
return self.detypedef().integer()
|
return self.detypedef().integer()
|
||||||
elif self.type.code == TypeCodeBitfield:
|
elif self.type.code == TypeCodeBitfield:
|
||||||
return self.lvalue
|
return self.lvalue
|
||||||
unsigned = self.type.name.startswith('unsigned')
|
# Could be something like 'short unsigned int'
|
||||||
|
unsigned = self.type.name == 'unsigned' \
|
||||||
|
or self.type.name.startswith('unsigned ') \
|
||||||
|
or self.type.name.find(' unsigned ') != -1
|
||||||
bitsize = self.type.bitsize()
|
bitsize = self.type.bitsize()
|
||||||
return self.extractInteger(bitsize, unsigned)
|
return self.extractInteger(bitsize, unsigned)
|
||||||
|
|
||||||
|
@@ -39,8 +39,9 @@ bool convertPosition(const QTextDocument *document, int pos, int *line, int *col
|
|||||||
(*column) = -1;
|
(*column) = -1;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
// line and column are both 1-based
|
||||||
(*line) = block.blockNumber() + 1;
|
(*line) = block.blockNumber() + 1;
|
||||||
(*column) = pos - block.position();
|
(*column) = pos - block.position() + 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -162,7 +162,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto runConfig = runner->runControl()->runConfiguration();
|
auto runConfig = runner->runControl()->runConfiguration();
|
||||||
auto aspect = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
|
auto aspect = runConfig->aspect<Debugger::DebuggerRunConfigurationAspect>();
|
||||||
Core::Id runMode = runner->runMode();
|
Core::Id runMode = runner->runMode();
|
||||||
const bool debuggingMode = runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE;
|
const bool debuggingMode = runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE;
|
||||||
m_useCppDebugger = debuggingMode && aspect->useCppDebugger();
|
m_useCppDebugger = debuggingMode && aspect->useCppDebugger();
|
||||||
@@ -194,23 +194,23 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
|
|||||||
m_deviceSerialNumber = AndroidManager::deviceSerialNumber(target);
|
m_deviceSerialNumber = AndroidManager::deviceSerialNumber(target);
|
||||||
m_apiLevel = AndroidManager::deviceApiLevel(target);
|
m_apiLevel = AndroidManager::deviceApiLevel(target);
|
||||||
|
|
||||||
m_extraEnvVars = runConfig->extraAspect<EnvironmentAspect>()->environment();
|
m_extraEnvVars = runConfig->aspect<EnvironmentAspect>()->environment();
|
||||||
qCDebug(androidRunWorkerLog) << "Environment variables for the app"
|
qCDebug(androidRunWorkerLog) << "Environment variables for the app"
|
||||||
<< m_extraEnvVars.toStringList();
|
<< m_extraEnvVars.toStringList();
|
||||||
|
|
||||||
m_extraAppParams = runConfig->runnable().commandLineArguments;
|
m_extraAppParams = runConfig->runnable().commandLineArguments;
|
||||||
|
|
||||||
if (auto aspect = runConfig->extraAspect(Constants::ANDROID_AMSTARTARGS))
|
if (auto aspect = runConfig->aspect(Constants::ANDROID_AMSTARTARGS))
|
||||||
m_amStartExtraArgs = static_cast<BaseStringAspect *>(aspect)->value().split(' ');
|
m_amStartExtraArgs = static_cast<BaseStringAspect *>(aspect)->value().split(' ');
|
||||||
|
|
||||||
if (auto aspect = runConfig->extraAspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) {
|
if (auto aspect = runConfig->aspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) {
|
||||||
for (const QString &shellCmd : static_cast<BaseStringListAspect *>(aspect)->value())
|
for (const QString &shellCmd : static_cast<BaseStringListAspect *>(aspect)->value())
|
||||||
m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
|
m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
|
||||||
}
|
}
|
||||||
for (const QString &shellCmd : runner->recordedData(Constants::ANDROID_PRESTARTSHELLCMDLIST).toStringList())
|
for (const QString &shellCmd : runner->recordedData(Constants::ANDROID_PRESTARTSHELLCMDLIST).toStringList())
|
||||||
m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
|
m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
|
||||||
|
|
||||||
if (auto aspect = runConfig->extraAspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) {
|
if (auto aspect = runConfig->aspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) {
|
||||||
for (const QString &shellCmd : static_cast<BaseStringListAspect *>(aspect)->value())
|
for (const QString &shellCmd : static_cast<BaseStringListAspect *>(aspect)->value())
|
||||||
m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd));
|
m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd));
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,7 @@ public:
|
|||||||
if (auto debuggable = dynamic_cast<DebuggableTestConfiguration *>(config))
|
if (auto debuggable = dynamic_cast<DebuggableTestConfiguration *>(config))
|
||||||
enableQuick = debuggable->mixedDebugging();
|
enableQuick = debuggable->mixedDebugging();
|
||||||
|
|
||||||
if (auto debugAspect = extraAspect<Debugger::DebuggerRunConfigurationAspect>()) {
|
if (auto debugAspect = aspect<Debugger::DebuggerRunConfigurationAspect>()) {
|
||||||
debugAspect->setUseQmlDebugger(enableQuick);
|
debugAspect->setUseQmlDebugger(enableQuick);
|
||||||
ProjectExplorer::ProjectExplorerPlugin::instance()->updateRunActions();
|
ProjectExplorer::ProjectExplorerPlugin::instance()->updateRunActions();
|
||||||
}
|
}
|
||||||
|
@@ -58,7 +58,7 @@ const char *BareMetalCustomRunConfiguration::Id = "BareMetal";
|
|||||||
|
|
||||||
bool BareMetalCustomRunConfiguration::isConfigured() const
|
bool BareMetalCustomRunConfiguration::isConfigured() const
|
||||||
{
|
{
|
||||||
return !extraAspect<ExecutableAspect>()->executable().isEmpty();
|
return !aspect<ExecutableAspect>()->executable().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
RunConfiguration::ConfigurationState
|
RunConfiguration::ConfigurationState
|
||||||
|
@@ -85,7 +85,7 @@ void BareMetalDebugSupport::start()
|
|||||||
{
|
{
|
||||||
const auto rc = runControl()->runConfiguration();
|
const auto rc = runControl()->runConfiguration();
|
||||||
QTC_ASSERT(rc, reportFailure(); return);
|
QTC_ASSERT(rc, reportFailure(); return);
|
||||||
const auto exeAspect = rc->extraAspect<ExecutableAspect>();
|
const auto exeAspect = rc->aspect<ExecutableAspect>();
|
||||||
QTC_ASSERT(exeAspect, reportFailure(); return);
|
QTC_ASSERT(exeAspect, reportFailure(); return);
|
||||||
|
|
||||||
const QString bin = exeAspect->executable().toString();
|
const QString bin = exeAspect->executable().toString();
|
||||||
@@ -124,7 +124,7 @@ void BareMetalDebugSupport::start()
|
|||||||
|
|
||||||
Runnable inferior;
|
Runnable inferior;
|
||||||
inferior.executable = bin;
|
inferior.executable = bin;
|
||||||
if (auto aspect = rc->extraAspect<ArgumentsAspect>())
|
if (auto aspect = rc->aspect<ArgumentsAspect>())
|
||||||
inferior.commandLineArguments = aspect->arguments(rc->macroExpander());
|
inferior.commandLineArguments = aspect->arguments(rc->macroExpander());
|
||||||
setInferior(inferior);
|
setInferior(inferior);
|
||||||
setSymbolFile(bin);
|
setSymbolFile(bin);
|
||||||
|
@@ -63,7 +63,7 @@ BareMetalRunConfiguration::BareMetalRunConfiguration(Target *target, Core::Id id
|
|||||||
void BareMetalRunConfiguration::updateTargetInformation()
|
void BareMetalRunConfiguration::updateTargetInformation()
|
||||||
{
|
{
|
||||||
const BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
|
const BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
|
||||||
extraAspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
|
aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
|
||||||
emit enabledChanged();
|
emit enabledChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "clangcompletionchunkstotextconverter.h"
|
#include "clangcompletionchunkstotextconverter.h"
|
||||||
#include "clangfixitoperation.h"
|
#include "clangfixitoperation.h"
|
||||||
|
#include "clangutils.h"
|
||||||
|
|
||||||
#include <cplusplus/Icons.h>
|
#include <cplusplus/Icons.h>
|
||||||
#include <cplusplus/MatchingText.h>
|
#include <cplusplus/MatchingText.h>
|
||||||
@@ -34,10 +35,13 @@
|
|||||||
#include <cplusplus/Token.h>
|
#include <cplusplus/Token.h>
|
||||||
|
|
||||||
#include <texteditor/completionsettings.h>
|
#include <texteditor/completionsettings.h>
|
||||||
|
#include <texteditor/texteditor.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QTextBlock>
|
||||||
#include <QTextCursor>
|
#include <QTextCursor>
|
||||||
|
#include <QTextDocument>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/textutils.h>
|
#include <utils/textutils.h>
|
||||||
@@ -45,6 +49,7 @@
|
|||||||
|
|
||||||
using namespace CPlusPlus;
|
using namespace CPlusPlus;
|
||||||
using namespace ClangBackEnd;
|
using namespace ClangBackEnd;
|
||||||
|
using namespace TextEditor;
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -73,7 +78,7 @@ bool ClangAssistProposalItem::implicitlyApplies() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString textUntilPreviousStatement(TextEditor::TextDocumentManipulatorInterface &manipulator,
|
static QString textUntilPreviousStatement(TextDocumentManipulatorInterface &manipulator,
|
||||||
int startPosition)
|
int startPosition)
|
||||||
{
|
{
|
||||||
static const QString stopCharacters(";{}#");
|
static const QString stopCharacters(";{}#");
|
||||||
@@ -90,7 +95,7 @@ static QString textUntilPreviousStatement(TextEditor::TextDocumentManipulatorInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 7.3.3: using typename(opt) nested-name-specifier unqualified-id ;
|
// 7.3.3: using typename(opt) nested-name-specifier unqualified-id ;
|
||||||
static bool isAtUsingDeclaration(TextEditor::TextDocumentManipulatorInterface &manipulator,
|
static bool isAtUsingDeclaration(TextDocumentManipulatorInterface &manipulator,
|
||||||
int basePosition)
|
int basePosition)
|
||||||
{
|
{
|
||||||
SimpleLexer lexer;
|
SimpleLexer lexer;
|
||||||
@@ -105,7 +110,7 @@ static bool isAtUsingDeclaration(TextEditor::TextDocumentManipulatorInterface &m
|
|||||||
if (lastToken.kind() != T_COLON_COLON)
|
if (lastToken.kind() != T_COLON_COLON)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return Utils::contains(tokens, [](const Token &token) {
|
return ::Utils::contains(tokens, [](const Token &token) {
|
||||||
return token.kind() == T_USING;
|
return token.kind() == T_USING;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -135,17 +140,17 @@ static QString methodDefinitionParameters(const CodeCompletionChunks &chunks)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface &manipulator,
|
void ClangAssistProposalItem::apply(TextDocumentManipulatorInterface &manipulator,
|
||||||
int basePosition) const
|
int basePosition) const
|
||||||
{
|
{
|
||||||
const CodeCompletion ccr = firstCodeCompletion();
|
const CodeCompletion ccr = firstCodeCompletion();
|
||||||
|
|
||||||
if (!ccr.requiredFixIts.empty()) {
|
if (!ccr.requiredFixIts.empty()) {
|
||||||
|
// Important: Calculate shift before changing the document.
|
||||||
|
basePosition += fixItsShift(manipulator);
|
||||||
|
|
||||||
ClangFixItOperation fixItOperation(Utf8String(), ccr.requiredFixIts);
|
ClangFixItOperation fixItOperation(Utf8String(), ccr.requiredFixIts);
|
||||||
fixItOperation.perform();
|
fixItOperation.perform();
|
||||||
|
|
||||||
const int shift = fixItsShift(manipulator);
|
|
||||||
basePosition += shift;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString textToBeInserted = m_text;
|
QString textToBeInserted = m_text;
|
||||||
@@ -175,8 +180,8 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
|
|||||||
|
|
||||||
textToBeInserted = converter.text();
|
textToBeInserted = converter.text();
|
||||||
} else if (!ccr.text.isEmpty()) {
|
} else if (!ccr.text.isEmpty()) {
|
||||||
const TextEditor::CompletionSettings &completionSettings =
|
const CompletionSettings &completionSettings =
|
||||||
TextEditor::TextEditorSettings::instance()->completionSettings();
|
TextEditorSettings::instance()->completionSettings();
|
||||||
const bool autoInsertBrackets = completionSettings.m_autoInsertBrackets;
|
const bool autoInsertBrackets = completionSettings.m_autoInsertBrackets;
|
||||||
|
|
||||||
if (autoInsertBrackets &&
|
if (autoInsertBrackets &&
|
||||||
@@ -193,9 +198,9 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
|
|||||||
QTextCursor cursor = manipulator.textCursorAt(basePosition);
|
QTextCursor cursor = manipulator.textCursorAt(basePosition);
|
||||||
|
|
||||||
bool abandonParen = false;
|
bool abandonParen = false;
|
||||||
if (Utils::Text::matchPreviousWord(manipulator, cursor, "&")) {
|
if (::Utils::Text::matchPreviousWord(manipulator, cursor, "&")) {
|
||||||
Utils::Text::moveToPrevChar(manipulator, cursor);
|
::Utils::Text::moveToPrevChar(manipulator, cursor);
|
||||||
Utils::Text::moveToPrevChar(manipulator, cursor);
|
::Utils::Text::moveToPrevChar(manipulator, cursor);
|
||||||
const QChar prevChar = manipulator.characterAt(cursor.position());
|
const QChar prevChar = manipulator.characterAt(cursor.position());
|
||||||
cursor.setPosition(basePosition);
|
cursor.setPosition(basePosition);
|
||||||
abandonParen = QString("(;,{}").contains(prevChar);
|
abandonParen = QString("(;,{}").contains(prevChar);
|
||||||
@@ -206,7 +211,7 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
|
|||||||
if (!abandonParen && ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind) {
|
if (!abandonParen && ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind) {
|
||||||
const CodeCompletionChunk resultType = ccr.chunks.first();
|
const CodeCompletionChunk resultType = ccr.chunks.first();
|
||||||
QTC_ASSERT(resultType.kind == CodeCompletionChunk::ResultType, return;);
|
QTC_ASSERT(resultType.kind == CodeCompletionChunk::ResultType, return;);
|
||||||
if (Utils::Text::matchPreviousWord(manipulator, cursor, resultType.text.toString())) {
|
if (::Utils::Text::matchPreviousWord(manipulator, cursor, resultType.text.toString())) {
|
||||||
extraCharacters += methodDefinitionParameters(ccr.chunks);
|
extraCharacters += methodDefinitionParameters(ccr.chunks);
|
||||||
// To skip the next block.
|
// To skip the next block.
|
||||||
abandonParen = true;
|
abandonParen = true;
|
||||||
@@ -306,7 +311,7 @@ void ClangAssistProposalItem::setText(const QString &text)
|
|||||||
|
|
||||||
QString ClangAssistProposalItem::text() const
|
QString ClangAssistProposalItem::text() const
|
||||||
{
|
{
|
||||||
return m_text + (requiresFixIts() ? fixItText() : QString());
|
return m_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVector<ClangBackEnd::FixItContainer> &ClangAssistProposalItem::firstCompletionFixIts() const
|
const QVector<ClangBackEnd::FixItContainer> &ClangAssistProposalItem::firstCompletionFixIts() const
|
||||||
@@ -314,39 +319,53 @@ const QVector<ClangBackEnd::FixItContainer> &ClangAssistProposalItem::firstCompl
|
|||||||
return firstCodeCompletion().requiredFixIts;
|
return firstCodeCompletion().requiredFixIts;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Indicate required fix-it without adding extra text.
|
std::pair<int, int> fixItPositionsRange(const FixItContainer &fixIt, const QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
const QTextBlock startLine = cursor.document()->findBlockByNumber(fixIt.range.start.line - 1);
|
||||||
|
const QTextBlock endLine = cursor.document()->findBlockByNumber(fixIt.range.end.line - 1);
|
||||||
|
|
||||||
|
const int fixItStartPos = ::Utils::Text::positionInText(
|
||||||
|
cursor.document(),
|
||||||
|
static_cast<int>(fixIt.range.start.line),
|
||||||
|
Utils::cppEditorColumn(startLine, static_cast<int>(fixIt.range.start.column)));
|
||||||
|
const int fixItEndPos = ::Utils::Text::positionInText(
|
||||||
|
cursor.document(),
|
||||||
|
static_cast<int>(fixIt.range.end.line),
|
||||||
|
Utils::cppEditorColumn(endLine, static_cast<int>(fixIt.range.end.column)));
|
||||||
|
return std::make_pair(fixItStartPos, fixItEndPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString textReplacedByFixit(const FixItContainer &fixIt)
|
||||||
|
{
|
||||||
|
TextEditorWidget *textEditorWidget = TextEditorWidget::currentTextEditorWidget();
|
||||||
|
if (!textEditorWidget)
|
||||||
|
return QString();
|
||||||
|
const std::pair<int, int> fixItPosRange = fixItPositionsRange(fixIt,
|
||||||
|
textEditorWidget->textCursor());
|
||||||
|
return textEditorWidget->textAt(fixItPosRange.first,
|
||||||
|
fixItPosRange.second - fixItPosRange.first);
|
||||||
|
}
|
||||||
|
|
||||||
QString ClangAssistProposalItem::fixItText() const
|
QString ClangAssistProposalItem::fixItText() const
|
||||||
{
|
{
|
||||||
const FixItContainer &fixIt = firstCompletionFixIts().first();
|
const FixItContainer &fixIt = firstCompletionFixIts().first();
|
||||||
const SourceRangeContainer &range = fixIt.range;
|
|
||||||
return QCoreApplication::translate("ClangCodeModel::ClangAssistProposalItem",
|
return QCoreApplication::translate("ClangCodeModel::ClangAssistProposalItem",
|
||||||
" (requires to correct [%1:%2-%3:%4] to \"%5\")")
|
"Requires to correct \"%1\" to \"%2\"")
|
||||||
.arg(range.start.line)
|
.arg(textReplacedByFixit(fixIt))
|
||||||
.arg(range.start.column)
|
|
||||||
.arg(range.end.line)
|
|
||||||
.arg(range.end.column)
|
|
||||||
.arg(fixIt.text.toString());
|
.arg(fixIt.text.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClangAssistProposalItem::fixItsShift(
|
int ClangAssistProposalItem::fixItsShift(const TextDocumentManipulatorInterface &manipulator) const
|
||||||
const TextEditor::TextDocumentManipulatorInterface &manipulator) const
|
|
||||||
{
|
{
|
||||||
const QVector<ClangBackEnd::FixItContainer> &requiredFixIts = firstCompletionFixIts();
|
const QVector<ClangBackEnd::FixItContainer> &requiredFixIts = firstCompletionFixIts();
|
||||||
if (requiredFixIts.empty())
|
if (requiredFixIts.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
QTextCursor cursor = manipulator.textCursorAt(0);
|
const QTextCursor cursor = manipulator.textCursorAt(0);
|
||||||
for (const FixItContainer &fixIt : requiredFixIts) {
|
for (const FixItContainer &fixIt : requiredFixIts) {
|
||||||
const int fixItStartPos = Utils::Text::positionInText(
|
const std::pair<int, int> fixItPosRange = fixItPositionsRange(fixIt, cursor);
|
||||||
cursor.document(),
|
shift += fixIt.text.toString().length() - (fixItPosRange.second - fixItPosRange.first);
|
||||||
static_cast<int>(fixIt.range.start.line),
|
|
||||||
static_cast<int>(fixIt.range.start.column));
|
|
||||||
const int fixItEndPos = Utils::Text::positionInText(
|
|
||||||
cursor.document(),
|
|
||||||
static_cast<int>(fixIt.range.end.line),
|
|
||||||
static_cast<int>(fixIt.range.end.column));
|
|
||||||
shift += fixIt.text.toString().length() - (fixItEndPos - fixItStartPos);
|
|
||||||
}
|
}
|
||||||
return shift;
|
return shift;
|
||||||
}
|
}
|
||||||
@@ -425,10 +444,14 @@ QString ClangAssistProposalItem::detail() const
|
|||||||
detail += "<br>";
|
detail += "<br>";
|
||||||
detail += CompletionChunksToTextConverter::convertToToolTipWithHtml(
|
detail += CompletionChunksToTextConverter::convertToToolTipWithHtml(
|
||||||
codeCompletion.chunks, codeCompletion.completionKind);
|
codeCompletion.chunks, codeCompletion.completionKind);
|
||||||
|
|
||||||
if (!codeCompletion.briefComment.isEmpty())
|
if (!codeCompletion.briefComment.isEmpty())
|
||||||
detail += "<br>" + codeCompletion.briefComment.toString();
|
detail += "<br>" + codeCompletion.briefComment.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requiresFixIts())
|
||||||
|
detail += "<br><br><b>" + fixItText() + "</b>";
|
||||||
|
|
||||||
return detail;
|
return detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,11 +56,7 @@ void ClangAssistProposalModel::sort(const QString &/*prefix*/)
|
|||||||
return static_cast<int>(first->prefixMatch())
|
return static_cast<int>(first->prefixMatch())
|
||||||
< static_cast<int>(second->prefixMatch());
|
< static_cast<int>(second->prefixMatch());
|
||||||
}
|
}
|
||||||
if (first->requiresFixIts() != second->requiresFixIts())
|
return false;
|
||||||
return first->requiresFixIts() < second->requiresFixIts();
|
|
||||||
return (first->order() > 0
|
|
||||||
&& (first->order() < second->order()
|
|
||||||
|| (first->order() == second->order() && first->text() < second->text())));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Keep the order for the items with the same priority and name.
|
// Keep the order for the items with the same priority and name.
|
||||||
|
@@ -51,8 +51,9 @@
|
|||||||
#include <clangsupport/filecontainer.h>
|
#include <clangsupport/filecontainer.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/textutils.h>
|
|
||||||
#include <utils/mimetypes/mimedatabase.h>
|
#include <utils/mimetypes/mimedatabase.h>
|
||||||
|
#include <utils/optional.h>
|
||||||
|
#include <utils/textutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
@@ -76,20 +77,18 @@ static void addAssistProposalItem(QList<AssistProposalItemInterface *> &items,
|
|||||||
item->appendCodeCompletion(codeCompletion);
|
item->appendCodeCompletion(codeCompletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the next CXXMethod or CXXConstructor which is the overload for another existing item.
|
||||||
static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterface *> &items,
|
static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterface *> &items,
|
||||||
AssistProposalItemInterface *sameItem,
|
AssistProposalItemInterface *sameItem,
|
||||||
const ClangCompletionAssistInterface *interface,
|
const ClangCompletionAssistInterface *interface,
|
||||||
const CodeCompletion &codeCompletion,
|
const CodeCompletion &codeCompletion,
|
||||||
const QString &name)
|
const QString &name)
|
||||||
{
|
{
|
||||||
ClangBackEnd::CodeCompletionChunk resultType = codeCompletion.chunks.first();
|
|
||||||
auto *item = static_cast<ClangAssistProposalItem *>(sameItem);
|
auto *item = static_cast<ClangAssistProposalItem *>(sameItem);
|
||||||
item->setHasOverloadsWithParameters(true);
|
item->setHasOverloadsWithParameters(true);
|
||||||
if (resultType.kind != ClangBackEnd::CodeCompletionChunk::ResultType) {
|
if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind) {
|
||||||
// It's the constructor.
|
// It's the constructor, currently constructor definitions do not lead here.
|
||||||
// CLANG-UPGRADE-CHECK: Can we get here with constructor definition?
|
// CLANG-UPGRADE-CHECK: Can we get here with constructor definition?
|
||||||
if (!item->firstCodeCompletion().hasParameters)
|
|
||||||
item->removeFirstCodeCompletion();
|
|
||||||
item->appendCodeCompletion(codeCompletion);
|
item->appendCodeCompletion(codeCompletion);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -98,15 +97,27 @@ static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterf
|
|||||||
cursor.setPosition(interface->position());
|
cursor.setPosition(interface->position());
|
||||||
cursor.movePosition(QTextCursor::StartOfWord);
|
cursor.movePosition(QTextCursor::StartOfWord);
|
||||||
|
|
||||||
|
const ClangBackEnd::CodeCompletionChunk resultType = codeCompletion.chunks.first();
|
||||||
if (::Utils::Text::matchPreviousWord(*interface->textEditorWidget(),
|
if (::Utils::Text::matchPreviousWord(*interface->textEditorWidget(),
|
||||||
cursor,
|
cursor,
|
||||||
resultType.text.toString())) {
|
resultType.text.toString())) {
|
||||||
|
// Function definition completion - do not merge completions together.
|
||||||
addAssistProposalItem(items, codeCompletion, name);
|
addAssistProposalItem(items, codeCompletion, name);
|
||||||
} else {
|
} else {
|
||||||
item->appendCodeCompletion(codeCompletion);
|
item->appendCodeCompletion(codeCompletion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if they are both CXXMethod or CXXConstructor.
|
||||||
|
static bool isTheSameFunctionOverload(const CodeCompletion &completion,
|
||||||
|
const QString &name,
|
||||||
|
ClangAssistProposalItem *lastItem)
|
||||||
|
{
|
||||||
|
return completion.hasParameters
|
||||||
|
&& completion.completionKind == lastItem->firstCodeCompletion().completionKind
|
||||||
|
&& lastItem->text() == name;
|
||||||
|
}
|
||||||
|
|
||||||
static QList<AssistProposalItemInterface *> toAssistProposalItems(
|
static QList<AssistProposalItemInterface *> toAssistProposalItems(
|
||||||
const CodeCompletions &completions,
|
const CodeCompletions &completions,
|
||||||
const ClangCompletionAssistInterface *interface)
|
const ClangCompletionAssistInterface *interface)
|
||||||
@@ -117,8 +128,9 @@ static QList<AssistProposalItemInterface *> toAssistProposalItems(
|
|||||||
QList<AssistProposalItemInterface *> items;
|
QList<AssistProposalItemInterface *> items;
|
||||||
items.reserve(completions.size());
|
items.reserve(completions.size());
|
||||||
for (const CodeCompletion &codeCompletion : completions) {
|
for (const CodeCompletion &codeCompletion : completions) {
|
||||||
if (codeCompletion.text.isEmpty()) // TODO: Make isValid()?
|
if (codeCompletion.text.isEmpty())
|
||||||
continue;
|
continue; // It's an OverloadCandidate which has text but no typedText.
|
||||||
|
|
||||||
if (signalCompletion && codeCompletion.completionKind != CodeCompletion::SignalCompletionKind)
|
if (signalCompletion && codeCompletion.completionKind != CodeCompletion::SignalCompletionKind)
|
||||||
continue;
|
continue;
|
||||||
if (slotCompletion && codeCompletion.completionKind != CodeCompletion::SlotCompletionKind)
|
if (slotCompletion && codeCompletion.completionKind != CodeCompletion::SlotCompletionKind)
|
||||||
@@ -128,34 +140,16 @@ static QList<AssistProposalItemInterface *> toAssistProposalItems(
|
|||||||
? CompletionChunksToTextConverter::convertToName(codeCompletion.chunks)
|
? CompletionChunksToTextConverter::convertToName(codeCompletion.chunks)
|
||||||
: codeCompletion.text.toString();
|
: codeCompletion.text.toString();
|
||||||
|
|
||||||
if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind
|
if (items.empty()) {
|
||||||
|| codeCompletion.completionKind == CodeCompletion::ClassCompletionKind) {
|
addAssistProposalItem(items, codeCompletion, name);
|
||||||
auto samePreviousConstructor
|
} else {
|
||||||
= std::find_if(items.begin(),
|
auto *lastItem = static_cast<ClangAssistProposalItem *>(items.last());
|
||||||
items.end(),
|
if (isTheSameFunctionOverload(codeCompletion, name, lastItem)) {
|
||||||
[&](const AssistProposalItemInterface *item) {
|
|
||||||
return item->text() == name
|
|
||||||
&& static_cast<const ClangAssistProposalItem *>(item)->firstCodeCompletion()
|
|
||||||
.completionKind == codeCompletion.completionKind;
|
|
||||||
});
|
|
||||||
if (samePreviousConstructor == items.end()) {
|
|
||||||
addAssistProposalItem(items, codeCompletion, name);
|
|
||||||
} else if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind){
|
|
||||||
addFunctionOverloadAssistProposalItem(items, *samePreviousConstructor, interface,
|
|
||||||
codeCompletion, name);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!items.empty() && items.last()->text() == name) {
|
|
||||||
if ((codeCompletion.completionKind == CodeCompletion::FunctionCompletionKind
|
|
||||||
|| codeCompletion.completionKind == CodeCompletion::FunctionDefinitionCompletionKind)
|
|
||||||
&& codeCompletion.hasParameters) {
|
|
||||||
addFunctionOverloadAssistProposalItem(items, items.back(), interface,
|
addFunctionOverloadAssistProposalItem(items, items.back(), interface,
|
||||||
codeCompletion, name);
|
codeCompletion, name);
|
||||||
|
} else {
|
||||||
|
addAssistProposalItem(items, codeCompletion, name);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
addAssistProposalItem(items, codeCompletion, name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,48 +181,14 @@ IAssistProposal *ClangCompletionAssistProcessor::perform(const AssistInterface *
|
|||||||
return startCompletionHelper(); // == 0 if results are calculated asynchronously
|
return startCompletionHelper(); // == 0 if results are calculated asynchronously
|
||||||
}
|
}
|
||||||
|
|
||||||
static CodeCompletions filterFunctionSignatures(const CodeCompletions &completions)
|
void ClangCompletionAssistProcessor::handleAvailableCompletions(const CodeCompletions &completions)
|
||||||
{
|
|
||||||
return ::Utils::filtered(completions, [](const CodeCompletion &completion) {
|
|
||||||
return completion.completionKind == CodeCompletion::FunctionOverloadCompletionKind;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static CodeCompletions filterConstructorSignatures(Utf8String textBefore,
|
|
||||||
const CodeCompletions &completions)
|
|
||||||
{
|
|
||||||
const int prevStatementEnd = textBefore.lastIndexOf(";");
|
|
||||||
if (prevStatementEnd != -1)
|
|
||||||
textBefore = textBefore.mid(prevStatementEnd + 1);
|
|
||||||
|
|
||||||
return ::Utils::filtered(completions, [&textBefore](const CodeCompletion &completion) {
|
|
||||||
if (completion.completionKind != CodeCompletion::ConstructorCompletionKind)
|
|
||||||
return false;
|
|
||||||
const Utf8String type = completion.chunks.at(0).text;
|
|
||||||
return textBefore.indexOf(type) != -1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangCompletionAssistProcessor::handleAvailableCompletions(
|
|
||||||
const CodeCompletions &completions)
|
|
||||||
{
|
{
|
||||||
QTC_CHECK(m_completions.isEmpty());
|
QTC_CHECK(m_completions.isEmpty());
|
||||||
|
|
||||||
if (m_sentRequestType == FunctionHintCompletion){
|
if (m_sentRequestType == FunctionHintCompletion) {
|
||||||
CodeCompletions functionSignatures;
|
const CodeCompletion &firstCompletion = completions.front();
|
||||||
if (m_completionOperator == T_LPAREN) {
|
if (firstCompletion.completionKind == CodeCompletion::FunctionOverloadCompletionKind) {
|
||||||
functionSignatures = filterFunctionSignatures(completions);
|
setAsyncProposalAvailable(createFunctionHintProposal(completions));
|
||||||
} else {
|
|
||||||
const QTextBlock block = m_interface->textDocument()->findBlock(
|
|
||||||
m_interface->position());
|
|
||||||
const QString textBefore = block.text().left(
|
|
||||||
m_interface->position() - block.position());
|
|
||||||
|
|
||||||
functionSignatures = filterConstructorSignatures(textBefore, completions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!functionSignatures.isEmpty()) {
|
|
||||||
setAsyncProposalAvailable(createFunctionHintProposal(functionSignatures));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// else: Proceed with a normal completion in case:
|
// else: Proceed with a normal completion in case:
|
||||||
|
@@ -155,8 +155,18 @@ int clangColumn(const QTextBlock &line, int cppEditorColumn)
|
|||||||
// (2) The return value is the column in Clang which is the utf8 byte offset from the beginning
|
// (2) The return value is the column in Clang which is the utf8 byte offset from the beginning
|
||||||
// of the line.
|
// of the line.
|
||||||
// Here we convert column from (1) to (2).
|
// Here we convert column from (1) to (2).
|
||||||
// '+ 1' is for 1-based columns
|
// '- 1' and '+ 1' are because of 1-based columns
|
||||||
return line.text().left(cppEditorColumn).toUtf8().size() + 1;
|
return line.text().left(cppEditorColumn - 1).toUtf8().size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cppEditorColumn(const QTextBlock &line, int clangColumn)
|
||||||
|
{
|
||||||
|
// (1) clangColumn is the column in Clang which is the utf8 byte offset from the beginning
|
||||||
|
// of the line.
|
||||||
|
// (2) The return value is the actual column shown by CppEditor.
|
||||||
|
// Here we convert column from (1) to (2).
|
||||||
|
// '- 1' and '+ 1' are because of 1-based columns
|
||||||
|
return QString::fromUtf8(line.text().toUtf8().left(clangColumn - 1)).size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
::Utils::CodeModelIcon::Type iconTypeForToken(const ClangBackEnd::TokenInfoContainer &token)
|
::Utils::CodeModelIcon::Type iconTypeForToken(const ClangBackEnd::TokenInfoContainer &token)
|
||||||
|
@@ -57,7 +57,8 @@ CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath);
|
|||||||
CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath);
|
CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath);
|
||||||
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
|
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
|
||||||
QString projectPartIdForFile(const QString &filePath);
|
QString projectPartIdForFile(const QString &filePath);
|
||||||
int clangColumn(const QTextBlock &lineText, int cppEditorColumn);
|
int clangColumn(const QTextBlock &line, int cppEditorColumn);
|
||||||
|
int cppEditorColumn(const QTextBlock &line, int clangColumn);
|
||||||
|
|
||||||
QString diagnosticCategoryPrefixRemoved(const QString &text);
|
QString diagnosticCategoryPrefixRemoved(const QString &text);
|
||||||
|
|
||||||
|
@@ -98,11 +98,11 @@ QString CMakeRunConfiguration::disabledReason() const
|
|||||||
void CMakeRunConfiguration::updateTargetInformation()
|
void CMakeRunConfiguration::updateTargetInformation()
|
||||||
{
|
{
|
||||||
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
|
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
|
||||||
extraAspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
|
aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
|
||||||
extraAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(bti.workingDirectory);
|
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(bti.workingDirectory);
|
||||||
extraAspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged();
|
aspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged();
|
||||||
|
|
||||||
auto terminalAspect = extraAspect<TerminalAspect>();
|
auto terminalAspect = aspect<TerminalAspect>();
|
||||||
if (!terminalAspect->isUserSet())
|
if (!terminalAspect->isUserSet())
|
||||||
terminalAspect->setUseTerminal(bti.usesTerminal);
|
terminalAspect->setUseTerminal(bti.usesTerminal);
|
||||||
}
|
}
|
||||||
|
@@ -69,10 +69,7 @@ bool TreeScanner::asyncScanForFiles(const Utils::FileName &directory)
|
|||||||
m_scanFuture = fi->future();
|
m_scanFuture = fi->future();
|
||||||
m_futureWatcher.setFuture(m_scanFuture);
|
m_futureWatcher.setFuture(m_scanFuture);
|
||||||
|
|
||||||
if (m_versionControls.isEmpty())
|
Utils::runAsync([this, fi, directory]() { TreeScanner::scanForFiles(fi, directory, m_filter, m_factory); });
|
||||||
m_versionControls = Core::VcsManager::versionControls();
|
|
||||||
|
|
||||||
Utils::runAsync([this, fi, directory]() { TreeScanner::scanForFiles(fi, directory, m_filter, m_factory, m_versionControls); });
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -150,14 +147,12 @@ FileType TreeScanner::genericFileType(const Utils::MimeType &mimeType, const Uti
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TreeScanner::scanForFiles(FutureInterface *fi, const Utils::FileName& directory,
|
void TreeScanner::scanForFiles(FutureInterface *fi, const Utils::FileName& directory,
|
||||||
const FileFilter &filter, const FileTypeFactory &factory,
|
const FileFilter &filter, const FileTypeFactory &factory)
|
||||||
QList<Core::IVersionControl *> &versionControls)
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<FutureInterface> fip(fi);
|
std::unique_ptr<FutureInterface> fip(fi);
|
||||||
fip->reportStarted();
|
fip->reportStarted();
|
||||||
|
|
||||||
Result nodes
|
Result nodes = FileNode::scanForFiles(
|
||||||
= FileNode::scanForFilesWithVersionControls(
|
|
||||||
directory,
|
directory,
|
||||||
[&filter, &factory](const Utils::FileName &fn) -> FileNode * {
|
[&filter, &factory](const Utils::FileName &fn) -> FileNode * {
|
||||||
const Utils::MimeType mimeType = Utils::mimeTypeForFile(fn.toString());
|
const Utils::MimeType mimeType = Utils::mimeTypeForFile(fn.toString());
|
||||||
@@ -172,7 +167,7 @@ void TreeScanner::scanForFiles(FutureInterface *fi, const Utils::FileName& direc
|
|||||||
type = factory(mimeType, fn);
|
type = factory(mimeType, fn);
|
||||||
|
|
||||||
return new FileNode(fn, type, false);
|
return new FileNode(fn, type, false);
|
||||||
}, versionControls, fip.get());
|
}, fip.get());
|
||||||
|
|
||||||
Utils::sort(nodes, ProjectExplorer::Node::sortByPath);
|
Utils::sort(nodes, ProjectExplorer::Node::sortByPath);
|
||||||
|
|
||||||
|
@@ -88,8 +88,7 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void scanForFiles(FutureInterface *fi, const Utils::FileName &directory,
|
static void scanForFiles(FutureInterface *fi, const Utils::FileName &directory,
|
||||||
const FileFilter &filter, const FileTypeFactory &factory,
|
const FileFilter &filter, const FileTypeFactory &factory);
|
||||||
QList<Core::IVersionControl *> &versionControls);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileFilter m_filter;
|
FileFilter m_filter;
|
||||||
@@ -97,7 +96,6 @@ private:
|
|||||||
|
|
||||||
FutureWatcher m_futureWatcher;
|
FutureWatcher m_futureWatcher;
|
||||||
Future m_scanFuture;
|
Future m_scanFuture;
|
||||||
QList<Core::IVersionControl *> m_versionControls;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -1682,9 +1682,8 @@ namespace {
|
|||||||
class ConvertToCamelCaseOp: public CppQuickFixOperation
|
class ConvertToCamelCaseOp: public CppQuickFixOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConvertToCamelCaseOp(const CppQuickFixInterface &interface, int priority,
|
ConvertToCamelCaseOp(const CppQuickFixInterface &interface, const QString &newName)
|
||||||
const QString &newName)
|
: CppQuickFixOperation(interface, -1)
|
||||||
: CppQuickFixOperation(interface, priority)
|
|
||||||
, m_name(newName)
|
, m_name(newName)
|
||||||
{
|
{
|
||||||
setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Camel Case"));
|
setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Camel Case"));
|
||||||
@@ -1744,7 +1743,7 @@ void ConvertToCamelCase::match(const CppQuickFixInterface &interface, QuickFixOp
|
|||||||
return;
|
return;
|
||||||
for (int i = 1; i < newName.length() - 1; ++i) {
|
for (int i = 1; i < newName.length() - 1; ++i) {
|
||||||
if (ConvertToCamelCaseOp::isConvertibleUnderscore(newName, i)) {
|
if (ConvertToCamelCaseOp::isConvertibleUnderscore(newName, i)) {
|
||||||
result << new ConvertToCamelCaseOp(interface, path.size() - 1, newName);
|
result << new ConvertToCamelCaseOp(interface, newName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3303,9 +3302,17 @@ public:
|
|||||||
|
|
||||||
// Write class qualification, if any.
|
// Write class qualification, if any.
|
||||||
if (matchingClass) {
|
if (matchingClass) {
|
||||||
const Name *name = rewriteName(matchingClass->name(), &env, control);
|
Class *current = matchingClass;
|
||||||
funcDef.append(printer.prettyName(name));
|
QVector<const Name *> classes{matchingClass->name()};
|
||||||
funcDef.append(QLatin1String("::"));
|
while (current->enclosingScope()->asClass()) {
|
||||||
|
current = current->enclosingScope()->asClass();
|
||||||
|
classes.prepend(current->name());
|
||||||
|
}
|
||||||
|
for (const Name *n : classes) {
|
||||||
|
const Name *name = rewriteName(n, &env, control);
|
||||||
|
funcDef.append(printer.prettyName(name));
|
||||||
|
funcDef.append(QLatin1String("::"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the extracted function itself and its call.
|
// Write the extracted function itself and its call.
|
||||||
|
@@ -906,9 +906,9 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer
|
|||||||
|
|
||||||
if (runConfig) {
|
if (runConfig) {
|
||||||
m_runParameters.displayName = runConfig->displayName();
|
m_runParameters.displayName = runConfig->displayName();
|
||||||
if (auto symbolsAspect = runConfig->extraAspect<SymbolFileAspect>())
|
if (auto symbolsAspect = runConfig->aspect<SymbolFileAspect>())
|
||||||
m_runParameters.symbolFile = symbolsAspect->value();
|
m_runParameters.symbolFile = symbolsAspect->value();
|
||||||
if (auto terminalAspect = runConfig->extraAspect<TerminalAspect>())
|
if (auto terminalAspect = runConfig->aspect<TerminalAspect>())
|
||||||
m_runParameters.useTerminal = terminalAspect->useTerminal();
|
m_runParameters.useTerminal = terminalAspect->useTerminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,7 +924,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer
|
|||||||
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(kit))
|
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(kit))
|
||||||
m_runParameters.qtPackageSourceLocation = qtVersion->qtPackageSourcePath().toString();
|
m_runParameters.qtPackageSourceLocation = qtVersion->qtPackageSourcePath().toString();
|
||||||
|
|
||||||
if (auto aspect = runConfig ? runConfig->extraAspect<DebuggerRunConfigurationAspect>() : nullptr) {
|
if (auto aspect = runConfig ? runConfig->aspect<DebuggerRunConfigurationAspect>() : nullptr) {
|
||||||
if (!aspect->useCppDebugger())
|
if (!aspect->useCppDebugger())
|
||||||
m_runParameters.cppEngineType = NoEngineType;
|
m_runParameters.cppEngineType = NoEngineType;
|
||||||
m_runParameters.isQmlDebugging = aspect->useQmlDebugger();
|
m_runParameters.isQmlDebugging = aspect->useQmlDebugger();
|
||||||
|
@@ -3385,8 +3385,14 @@ GitRemote::GitRemote(const QString &url)
|
|||||||
|
|
||||||
// Check for local remotes (refer to the root or relative path)
|
// Check for local remotes (refer to the root or relative path)
|
||||||
// On Windows, local paths typically starts with <drive>:
|
// On Windows, local paths typically starts with <drive>:
|
||||||
|
auto startsWithWindowsDrive = [](const QString &url) {
|
||||||
|
if (!HostOsInfo::isWindowsHost() || url.size() < 2)
|
||||||
|
return false;
|
||||||
|
const QChar drive = url.at(0).toLower();
|
||||||
|
return drive >= 'a' && drive <= 'z' && url.at(1) == ':';
|
||||||
|
};
|
||||||
if (url.startsWith("file://") || url.startsWith('/') || url.startsWith('.')
|
if (url.startsWith("file://") || url.startsWith('/') || url.startsWith('.')
|
||||||
|| (HostOsInfo::isWindowsHost() && url[1] == ':')) {
|
|| startsWithWindowsDrive(url)) {
|
||||||
protocol = "file";
|
protocol = "file";
|
||||||
path = QDir::fromNativeSeparators(url.startsWith("file://") ? url.mid(7) : url);
|
path = QDir::fromNativeSeparators(url.startsWith("file://") ? url.mid(7) : url);
|
||||||
isValid = QDir(path).exists() || QDir(path + ".git").exists();
|
isValid = QDir(path).exists() || QDir(path + ".git").exists();
|
||||||
|
@@ -82,7 +82,10 @@ bool GitVersionControl::isVcsFileOrDirectory(const Utils::FileName &fileName) co
|
|||||||
return false;
|
return false;
|
||||||
if (fileName.toFileInfo().isDir())
|
if (fileName.toFileInfo().isDir())
|
||||||
return true;
|
return true;
|
||||||
return QFile(fileName.toString()).readLine().startsWith("gitdir: ");
|
QFile file(fileName.toString());
|
||||||
|
if (!file.open(QFile::ReadOnly))
|
||||||
|
return false;
|
||||||
|
return file.read(8) == "gitdir: ";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitVersionControl::isConfigured() const
|
bool GitVersionControl::isConfigured() const
|
||||||
|
@@ -84,11 +84,6 @@ struct HelpManagerPrivate
|
|||||||
static HelpManager *m_instance = nullptr;
|
static HelpManager *m_instance = nullptr;
|
||||||
static HelpManagerPrivate *d = nullptr;
|
static HelpManagerPrivate *d = nullptr;
|
||||||
|
|
||||||
static const char linksForKeyQuery[] = "SELECT d.Title, f.Name, e.Name, "
|
|
||||||
"d.Name, a.Anchor FROM IndexTable a, FileNameTable d, FolderTable e, "
|
|
||||||
"NamespaceTable f WHERE a.FileId=d.FileId AND d.FolderId=e.Id AND "
|
|
||||||
"a.NamespaceId=f.Id AND a.Name='%1'";
|
|
||||||
|
|
||||||
// -- DbCleaner
|
// -- DbCleaner
|
||||||
|
|
||||||
struct DbCleaner
|
struct DbCleaner
|
||||||
@@ -227,66 +222,29 @@ QSet<QString> HelpManager::userDocumentationPaths()
|
|||||||
return d->m_userRegisteredFiles;
|
return d->m_userRegisteredFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QUrl buildQUrl(const QString &ns, const QString &folder,
|
|
||||||
const QString &relFileName, const QString &anchor)
|
|
||||||
{
|
|
||||||
QUrl url;
|
|
||||||
url.setScheme(QLatin1String("qthelp"));
|
|
||||||
url.setAuthority(ns);
|
|
||||||
url.setPath(QLatin1Char('/') + folder + QLatin1Char('/') + relFileName);
|
|
||||||
url.setFragment(anchor);
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should go into Qt 4.8 once we start using it for Qt Creator
|
// This should go into Qt 4.8 once we start using it for Qt Creator
|
||||||
QMap<QString, QUrl> HelpManager::linksForKeyword(const QString &key)
|
QMap<QString, QUrl> HelpManager::linksForKeyword(const QString &key)
|
||||||
{
|
{
|
||||||
QMap<QString, QUrl> links;
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
QTC_ASSERT(!d->m_needsSetup, return links);
|
return d->m_helpEngine->linksForKeyword(key);
|
||||||
|
|
||||||
const QLatin1String sqlite("QSQLITE");
|
|
||||||
const QLatin1String name("HelpManager::linksForKeyword");
|
|
||||||
|
|
||||||
DbCleaner cleaner(name);
|
|
||||||
QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name);
|
|
||||||
if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) {
|
|
||||||
const QStringList ®isteredDocs = d->m_helpEngine->registeredDocumentations();
|
|
||||||
for (const QString &nameSpace : registeredDocs) {
|
|
||||||
db.setDatabaseName(d->m_helpEngine->documentationFileName(nameSpace));
|
|
||||||
if (db.open()) {
|
|
||||||
QSqlQuery query = QSqlQuery(db);
|
|
||||||
query.setForwardOnly(true);
|
|
||||||
query.exec(QString::fromLatin1(linksForKeyQuery).arg(key));
|
|
||||||
while (query.next()) {
|
|
||||||
QString title = query.value(0).toString();
|
|
||||||
if (title.isEmpty()) // generate a title + corresponding path
|
|
||||||
title = key + QLatin1String(" : ") + query.value(3).toString();
|
|
||||||
links.insertMulti(title, buildQUrl(query.value(1).toString(),
|
|
||||||
query.value(2).toString(), query.value(3).toString(),
|
|
||||||
query.value(4).toString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return links;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, QUrl> HelpManager::linksForIdentifier(const QString &id)
|
QMap<QString, QUrl> HelpManager::linksForIdentifier(const QString &id)
|
||||||
{
|
{
|
||||||
QMap<QString, QUrl> empty;
|
QMap<QString, QUrl> empty;
|
||||||
QTC_ASSERT(!d->m_needsSetup, return empty);
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
return d->m_helpEngine->linksForIdentifier(id);
|
return d->m_helpEngine->linksForIdentifier(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl HelpManager::findFile(const QUrl &url)
|
QUrl HelpManager::findFile(const QUrl &url)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_needsSetup, return QUrl());
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
return d->m_helpEngine->findFile(url);
|
return d->m_helpEngine->findFile(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray HelpManager::fileData(const QUrl &url)
|
QByteArray HelpManager::fileData(const QUrl &url)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_needsSetup, return QByteArray());
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
return d->m_helpEngine->fileData(url);
|
return d->m_helpEngine->fileData(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,19 +255,19 @@ void HelpManager::handleHelpRequest(const QUrl &url, Core::HelpManager::HelpView
|
|||||||
|
|
||||||
QStringList HelpManager::registeredNamespaces()
|
QStringList HelpManager::registeredNamespaces()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_needsSetup, return QStringList());
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
return d->m_helpEngine->registeredDocumentations();
|
return d->m_helpEngine->registeredDocumentations();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HelpManager::namespaceFromFile(const QString &file)
|
QString HelpManager::namespaceFromFile(const QString &file)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_needsSetup, return QString());
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
return d->m_helpEngine->namespaceName(file);
|
return d->m_helpEngine->namespaceName(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HelpManager::fileFromNamespace(const QString &nameSpace)
|
QString HelpManager::fileFromNamespace(const QString &nameSpace)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_needsSetup, return QString());
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
return d->m_helpEngine->documentationFileName(nameSpace);
|
return d->m_helpEngine->documentationFileName(nameSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,13 +283,13 @@ void HelpManager::setCustomValue(const QString &key, const QVariant &value)
|
|||||||
|
|
||||||
QVariant HelpManager::customValue(const QString &key, const QVariant &value)
|
QVariant HelpManager::customValue(const QString &key, const QVariant &value)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_needsSetup, return QVariant());
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
return d->m_helpEngine->customValue(key, value);
|
return d->m_helpEngine->customValue(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
HelpManager::Filters HelpManager::filters()
|
HelpManager::Filters HelpManager::filters()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_needsSetup, return Filters());
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
|
|
||||||
Filters filters;
|
Filters filters;
|
||||||
const QStringList &customFilters = d->m_helpEngine->customFilters();
|
const QStringList &customFilters = d->m_helpEngine->customFilters();
|
||||||
@@ -342,12 +300,12 @@ HelpManager::Filters HelpManager::filters()
|
|||||||
|
|
||||||
HelpManager::Filters HelpManager::fixedFilters()
|
HelpManager::Filters HelpManager::fixedFilters()
|
||||||
{
|
{
|
||||||
Filters fixedFilters;
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
QTC_ASSERT(!d->m_needsSetup, return fixedFilters);
|
|
||||||
|
|
||||||
const QLatin1String sqlite("QSQLITE");
|
const QLatin1String sqlite("QSQLITE");
|
||||||
const QLatin1String name("HelpManager::fixedCustomFilters");
|
const QLatin1String name("HelpManager::fixedCustomFilters");
|
||||||
|
|
||||||
|
Filters fixedFilters;
|
||||||
DbCleaner cleaner(name);
|
DbCleaner cleaner(name);
|
||||||
QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name);
|
QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name);
|
||||||
if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) {
|
if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) {
|
||||||
@@ -370,7 +328,7 @@ HelpManager::Filters HelpManager::fixedFilters()
|
|||||||
|
|
||||||
HelpManager::Filters HelpManager::userDefinedFilters()
|
HelpManager::Filters HelpManager::userDefinedFilters()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_needsSetup, return Filters());
|
QTC_ASSERT(!d->m_needsSetup, return {});
|
||||||
|
|
||||||
Filters all = filters();
|
Filters all = filters();
|
||||||
const Filters &fixed = fixedFilters();
|
const Filters &fixed = fixedFilters();
|
||||||
|
@@ -139,7 +139,7 @@ void IosRunConfiguration::updateDisplayNames()
|
|||||||
setDefaultDisplayName(tr("Run on %1").arg(devName));
|
setDefaultDisplayName(tr("Run on %1").arg(devName));
|
||||||
setDisplayName(tr("Run %1 on %2").arg(applicationName()).arg(devName));
|
setDisplayName(tr("Run %1 on %2").arg(applicationName()).arg(devName));
|
||||||
|
|
||||||
extraAspect<ExecutableAspect>()->setExecutable(localExecutable());
|
aspect<ExecutableAspect>()->setExecutable(localExecutable());
|
||||||
}
|
}
|
||||||
|
|
||||||
void IosRunConfiguration::updateEnabledState()
|
void IosRunConfiguration::updateEnabledState()
|
||||||
|
@@ -100,7 +100,7 @@ IosRunner::IosRunner(RunControl *runControl)
|
|||||||
stopRunningRunControl(runControl);
|
stopRunningRunControl(runControl);
|
||||||
auto runConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration());
|
auto runConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration());
|
||||||
m_bundleDir = runConfig->bundleDirectory().toString();
|
m_bundleDir = runConfig->bundleDirectory().toString();
|
||||||
m_arguments = runConfig->extraAspect<ArgumentsAspect>()->arguments(runConfig->macroExpander());
|
m_arguments = runConfig->aspect<ArgumentsAspect>()->arguments(runConfig->macroExpander());
|
||||||
m_device = DeviceKitInformation::device(runConfig->target()->kit());
|
m_device = DeviceKitInformation::device(runConfig->target()->kit());
|
||||||
m_deviceType = runConfig->deviceType();
|
m_deviceType = runConfig->deviceType();
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,7 @@ IosQmlProfilerSupport::IosQmlProfilerSupport(RunControl *runControl)
|
|||||||
Runnable runnable;
|
Runnable runnable;
|
||||||
runnable.executable = iosRunConfig->localExecutable().toUserOutput();
|
runnable.executable = iosRunConfig->localExecutable().toUserOutput();
|
||||||
runnable.commandLineArguments =
|
runnable.commandLineArguments =
|
||||||
iosRunConfig->extraAspect<ArgumentsAspect>()->arguments(iosRunConfig->macroExpander());
|
iosRunConfig->aspect<ArgumentsAspect>()->arguments(iosRunConfig->macroExpander());
|
||||||
runControl->setDisplayName(iosRunConfig->applicationName());
|
runControl->setDisplayName(iosRunConfig->applicationName());
|
||||||
runControl->setRunnable(runnable);
|
runControl->setRunnable(runnable);
|
||||||
|
|
||||||
|
@@ -113,11 +113,9 @@ void NimProject::collectProjectFiles()
|
|||||||
m_lastProjectScan.start();
|
m_lastProjectScan.start();
|
||||||
QTC_ASSERT(!m_futureWatcher.future().isRunning(), return);
|
QTC_ASSERT(!m_futureWatcher.future().isRunning(), return);
|
||||||
FileName prjDir = projectDirectory();
|
FileName prjDir = projectDirectory();
|
||||||
const QList<Core::IVersionControl *> versionControls = Core::VcsManager::versionControls();
|
QFuture<QList<ProjectExplorer::FileNode *>> future = Utils::runAsync([prjDir] {
|
||||||
QFuture<QList<ProjectExplorer::FileNode *>> future = Utils::runAsync([prjDir, versionControls] {
|
return FileNode::scanForFiles(
|
||||||
return FileNode::scanForFilesWithVersionControls(
|
prjDir, [](const FileName &fn) { return new FileNode(fn, FileType::Source, false); });
|
||||||
prjDir, [](const FileName &fn) { return new FileNode(fn, FileType::Source, false); },
|
|
||||||
versionControls);
|
|
||||||
});
|
});
|
||||||
m_futureWatcher.setFuture(future);
|
m_futureWatcher.setFuture(future);
|
||||||
Core::ProgressManager::addTask(future, tr("Scanning for Nim files"), "Nim.Project.Scan");
|
Core::ProgressManager::addTask(future, tr("Scanning for Nim files"), "Nim.Project.Scan");
|
||||||
@@ -144,7 +142,7 @@ void NimProject::updateProject()
|
|||||||
m_files = transform<QList>(fileNodes, [](const std::unique_ptr<FileNode> &fn) {
|
m_files = transform<QList>(fileNodes, [](const std::unique_ptr<FileNode> &fn) {
|
||||||
return fn->filePath().toString();
|
return fn->filePath().toString();
|
||||||
});
|
});
|
||||||
Utils::sort(m_files, [](const QString &a, const QString &b) { return a < b; });
|
Utils::sort(m_files);
|
||||||
|
|
||||||
if (oldFiles == m_files)
|
if (oldFiles == m_files)
|
||||||
return;
|
return;
|
||||||
|
@@ -67,9 +67,9 @@ void NimRunConfiguration::updateConfiguration()
|
|||||||
QTC_ASSERT(buildConfiguration, return);
|
QTC_ASSERT(buildConfiguration, return);
|
||||||
setActiveBuildConfiguration(buildConfiguration);
|
setActiveBuildConfiguration(buildConfiguration);
|
||||||
const QFileInfo outFileInfo = buildConfiguration->outFilePath().toFileInfo();
|
const QFileInfo outFileInfo = buildConfiguration->outFilePath().toFileInfo();
|
||||||
extraAspect<ExecutableAspect>()->setExecutable(FileName::fromString(outFileInfo.absoluteFilePath()));
|
aspect<ExecutableAspect>()->setExecutable(FileName::fromString(outFileInfo.absoluteFilePath()));
|
||||||
const QString workingDirectory = outFileInfo.absoluteDir().absolutePath();
|
const QString workingDirectory = outFileInfo.absoluteDir().absolutePath();
|
||||||
extraAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(FileName::fromString(workingDirectory));
|
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(FileName::fromString(workingDirectory));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NimRunConfiguration::setActiveBuildConfiguration(NimBuildConfiguration *activeBuildConfiguration)
|
void NimRunConfiguration::setActiveBuildConfiguration(NimBuildConfiguration *activeBuildConfiguration)
|
||||||
|
@@ -94,7 +94,7 @@ private:
|
|||||||
CustomExecutableDialog::CustomExecutableDialog(RunConfiguration *rc)
|
CustomExecutableDialog::CustomExecutableDialog(RunConfiguration *rc)
|
||||||
: QDialog(Core::ICore::dialogParent()),
|
: QDialog(Core::ICore::dialogParent()),
|
||||||
m_rc(rc),
|
m_rc(rc),
|
||||||
m_workingDirectory(rc->extraAspect<EnvironmentAspect>())
|
m_workingDirectory(rc->aspect<EnvironmentAspect>())
|
||||||
{
|
{
|
||||||
auto vbox = new QVBoxLayout(this);
|
auto vbox = new QVBoxLayout(this);
|
||||||
vbox->addWidget(new QLabel(tr("Could not find the executable, please specify one.")));
|
vbox->addWidget(new QLabel(tr("Could not find the executable, please specify one.")));
|
||||||
@@ -121,21 +121,21 @@ CustomExecutableDialog::CustomExecutableDialog(RunConfiguration *rc)
|
|||||||
m_executableChooser = new PathChooser(this);
|
m_executableChooser = new PathChooser(this);
|
||||||
m_executableChooser->setHistoryCompleter("Qt.CustomExecutable.History");
|
m_executableChooser->setHistoryCompleter("Qt.CustomExecutable.History");
|
||||||
m_executableChooser->setExpectedKind(PathChooser::ExistingCommand);
|
m_executableChooser->setExpectedKind(PathChooser::ExistingCommand);
|
||||||
m_executableChooser->setPath(rc->extraAspect<ExecutableAspect>()->executable().toString());
|
m_executableChooser->setPath(rc->aspect<ExecutableAspect>()->executable().toString());
|
||||||
layout->addRow(tr("Executable:"), m_executableChooser);
|
layout->addRow(tr("Executable:"), m_executableChooser);
|
||||||
connect(m_executableChooser, &PathChooser::rawPathChanged,
|
connect(m_executableChooser, &PathChooser::rawPathChanged,
|
||||||
this, &CustomExecutableDialog::changed);
|
this, &CustomExecutableDialog::changed);
|
||||||
|
|
||||||
copyAspect(rc->extraAspect<ArgumentsAspect>(), &m_arguments);
|
copyAspect(rc->aspect<ArgumentsAspect>(), &m_arguments);
|
||||||
m_arguments.addToConfigurationLayout(layout);
|
m_arguments.addToConfigurationLayout(layout);
|
||||||
|
|
||||||
copyAspect(rc->extraAspect<WorkingDirectoryAspect>(), &m_workingDirectory);
|
copyAspect(rc->aspect<WorkingDirectoryAspect>(), &m_workingDirectory);
|
||||||
m_workingDirectory.addToConfigurationLayout(layout);
|
m_workingDirectory.addToConfigurationLayout(layout);
|
||||||
|
|
||||||
copyAspect(rc->extraAspect<TerminalAspect>(), &m_terminal);
|
copyAspect(rc->aspect<TerminalAspect>(), &m_terminal);
|
||||||
m_terminal.addToConfigurationLayout(layout);
|
m_terminal.addToConfigurationLayout(layout);
|
||||||
|
|
||||||
auto enviromentAspect = rc->extraAspect<EnvironmentAspect>();
|
auto enviromentAspect = rc->aspect<EnvironmentAspect>();
|
||||||
connect(enviromentAspect, &EnvironmentAspect::environmentChanged,
|
connect(enviromentAspect, &EnvironmentAspect::environmentChanged,
|
||||||
this, &CustomExecutableDialog::environmentWasChanged);
|
this, &CustomExecutableDialog::environmentWasChanged);
|
||||||
environmentWasChanged();
|
environmentWasChanged();
|
||||||
@@ -146,10 +146,10 @@ CustomExecutableDialog::CustomExecutableDialog(RunConfiguration *rc)
|
|||||||
void CustomExecutableDialog::accept()
|
void CustomExecutableDialog::accept()
|
||||||
{
|
{
|
||||||
auto executable = FileName::fromString(m_executableChooser->path());
|
auto executable = FileName::fromString(m_executableChooser->path());
|
||||||
m_rc->extraAspect<ExecutableAspect>()->setExecutable(executable);
|
m_rc->aspect<ExecutableAspect>()->setExecutable(executable);
|
||||||
copyAspect(&m_arguments, m_rc->extraAspect<ArgumentsAspect>());
|
copyAspect(&m_arguments, m_rc->aspect<ArgumentsAspect>());
|
||||||
copyAspect(&m_workingDirectory, m_rc->extraAspect<WorkingDirectoryAspect>());
|
copyAspect(&m_workingDirectory, m_rc->aspect<WorkingDirectoryAspect>());
|
||||||
copyAspect(&m_terminal, m_rc->extraAspect<TerminalAspect>());
|
copyAspect(&m_terminal, m_rc->aspect<TerminalAspect>());
|
||||||
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ bool CustomExecutableDialog::event(QEvent *event)
|
|||||||
|
|
||||||
void CustomExecutableDialog::environmentWasChanged()
|
void CustomExecutableDialog::environmentWasChanged()
|
||||||
{
|
{
|
||||||
auto aspect = m_rc->extraAspect<EnvironmentAspect>();
|
auto aspect = m_rc->aspect<EnvironmentAspect>();
|
||||||
QTC_ASSERT(aspect, return);
|
QTC_ASSERT(aspect, return);
|
||||||
m_executableChooser->setEnvironment(aspect->environment());
|
m_executableChooser->setEnvironment(aspect->environment());
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@ void CustomExecutableRunConfiguration::configurationDialogFinished()
|
|||||||
|
|
||||||
QString CustomExecutableRunConfiguration::rawExecutable() const
|
QString CustomExecutableRunConfiguration::rawExecutable() const
|
||||||
{
|
{
|
||||||
return extraAspect<ExecutableAspect>()->executable().toString();
|
return aspect<ExecutableAspect>()->executable().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CustomExecutableRunConfiguration::isConfigured() const
|
bool CustomExecutableRunConfiguration::isConfigured() const
|
||||||
@@ -253,12 +253,12 @@ bool CustomExecutableRunConfiguration::isConfigured() const
|
|||||||
Runnable CustomExecutableRunConfiguration::runnable() const
|
Runnable CustomExecutableRunConfiguration::runnable() const
|
||||||
{
|
{
|
||||||
FileName workingDirectory =
|
FileName workingDirectory =
|
||||||
extraAspect<WorkingDirectoryAspect>()->workingDirectory(macroExpander());
|
aspect<WorkingDirectoryAspect>()->workingDirectory(macroExpander());
|
||||||
|
|
||||||
Runnable r;
|
Runnable r;
|
||||||
r.executable = extraAspect<ExecutableAspect>()->executable().toString();
|
r.executable = aspect<ExecutableAspect>()->executable().toString();
|
||||||
r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments(macroExpander());
|
r.commandLineArguments = aspect<ArgumentsAspect>()->arguments(macroExpander());
|
||||||
r.environment = extraAspect<EnvironmentAspect>()->environment();
|
r.environment = aspect<EnvironmentAspect>()->environment();
|
||||||
r.workingDirectory = workingDirectory.toString();
|
r.workingDirectory = workingDirectory.toString();
|
||||||
r.device = DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE);
|
r.device = DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE);
|
||||||
|
|
||||||
|
@@ -154,7 +154,7 @@ bool ProjectConfiguration::fromMap(const QVariantMap &map)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectConfigurationAspect *ProjectConfiguration::extraAspect(Core::Id id) const
|
ProjectConfigurationAspect *ProjectConfiguration::aspect(Core::Id id) const
|
||||||
{
|
{
|
||||||
return Utils::findOrDefault(m_aspects, Utils::equal(&ProjectConfigurationAspect::id, id));
|
return Utils::findOrDefault(m_aspects, Utils::equal(&ProjectConfigurationAspect::id, id));
|
||||||
}
|
}
|
||||||
|
@@ -126,9 +126,9 @@ public:
|
|||||||
|
|
||||||
const QList<ProjectConfigurationAspect *> aspects() const { return m_aspects; }
|
const QList<ProjectConfigurationAspect *> aspects() const { return m_aspects; }
|
||||||
|
|
||||||
ProjectConfigurationAspect *extraAspect(Core::Id id) const;
|
ProjectConfigurationAspect *aspect(Core::Id id) const;
|
||||||
|
|
||||||
template <typename T> T *extraAspect() const
|
template <typename T> T *aspect() const
|
||||||
{
|
{
|
||||||
for (ProjectConfigurationAspect *aspect : m_aspects)
|
for (ProjectConfigurationAspect *aspect : m_aspects)
|
||||||
if (T *result = qobject_cast<T *>(aspect))
|
if (T *result = qobject_cast<T *>(aspect))
|
||||||
|
@@ -390,15 +390,15 @@ static QList<FileNode *> scanForFilesRecursively(const Utils::FileName &director
|
|||||||
}
|
}
|
||||||
|
|
||||||
QList<FileNode *>
|
QList<FileNode *>
|
||||||
FileNode::scanForFilesWithVersionControls(const Utils::FileName &directory,
|
FileNode::scanForFiles(const Utils::FileName &directory,
|
||||||
const std::function<FileNode *(const Utils::FileName &)> factory,
|
const std::function<FileNode *(const Utils::FileName &)> factory,
|
||||||
const QList<Core::IVersionControl *> &versionControls,
|
QFutureInterface<QList<FileNode *>> *future)
|
||||||
QFutureInterface<QList<FileNode *>> *future)
|
|
||||||
{
|
{
|
||||||
QSet<QString> visited;
|
QSet<QString> visited;
|
||||||
if (future)
|
if (future)
|
||||||
future->setProgressRange(0, 1000000);
|
future->setProgressRange(0, 1000000);
|
||||||
return scanForFilesRecursively(directory, factory, visited, future, 0.0, 1000000.0, versionControls);
|
return scanForFilesRecursively(directory, factory, visited, future, 0.0, 1000000.0,
|
||||||
|
Core::VcsManager::versionControls());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileNode::supportsAction(ProjectAction action, const Node *node) const
|
bool FileNode::supportsAction(ProjectAction action, const Node *node) const
|
||||||
|
@@ -36,7 +36,6 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace Utils { class MimeType; }
|
namespace Utils { class MimeType; }
|
||||||
namespace Core { class IVersionControl; }
|
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
@@ -191,10 +190,9 @@ public:
|
|||||||
const FileNode *asFileNode() const final { return this; }
|
const FileNode *asFileNode() const final { return this; }
|
||||||
|
|
||||||
static QList<FileNode *>
|
static QList<FileNode *>
|
||||||
scanForFilesWithVersionControls(const Utils::FileName &directory,
|
scanForFiles(const Utils::FileName &directory,
|
||||||
const std::function<FileNode *(const Utils::FileName &fileName)> factory,
|
const std::function<FileNode *(const Utils::FileName &fileName)> factory,
|
||||||
const QList<Core::IVersionControl *> &versionControls,
|
QFutureInterface<QList<FileNode *>> *future = nullptr);
|
||||||
QFutureInterface<QList<FileNode *>> *future = nullptr);
|
|
||||||
bool supportsAction(ProjectAction action, const Node *node) const override;
|
bool supportsAction(ProjectAction action, const Node *node) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -193,7 +193,7 @@ RunConfiguration::RunConfiguration(Target *target, Core::Id id)
|
|||||||
});
|
});
|
||||||
expander->registerPrefix("CurrentRun:Env", tr("Variables in the current run environment"),
|
expander->registerPrefix("CurrentRun:Env", tr("Variables in the current run environment"),
|
||||||
[this](const QString &var) {
|
[this](const QString &var) {
|
||||||
const auto envAspect = extraAspect<EnvironmentAspect>();
|
const auto envAspect = aspect<EnvironmentAspect>();
|
||||||
return envAspect ? envAspect->environment().value(var) : QString();
|
return envAspect ? envAspect->environment().value(var) : QString();
|
||||||
});
|
});
|
||||||
expander->registerVariable(Constants::VAR_CURRENTRUN_NAME,
|
expander->registerVariable(Constants::VAR_CURRENTRUN_NAME,
|
||||||
@@ -224,6 +224,8 @@ QWidget *RunConfiguration::createConfigurationWidget()
|
|||||||
{
|
{
|
||||||
auto widget = new QWidget;
|
auto widget = new QWidget;
|
||||||
auto formLayout = new QFormLayout(widget);
|
auto formLayout = new QFormLayout(widget);
|
||||||
|
formLayout->setMargin(0);
|
||||||
|
formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
||||||
|
|
||||||
for (ProjectConfigurationAspect *aspect : m_aspects) {
|
for (ProjectConfigurationAspect *aspect : m_aspects) {
|
||||||
if (aspect->isVisible())
|
if (aspect->isVisible())
|
||||||
@@ -232,7 +234,10 @@ QWidget *RunConfiguration::createConfigurationWidget()
|
|||||||
|
|
||||||
Core::VariableChooser::addSupportForChildWidgets(widget, macroExpander());
|
Core::VariableChooser::addSupportForChildWidgets(widget, macroExpander());
|
||||||
|
|
||||||
return wrapWidget(widget);
|
auto detailsWidget = new Utils::DetailsWidget;
|
||||||
|
detailsWidget->setState(DetailsWidget::NoSummary);
|
||||||
|
detailsWidget->setWidget(widget);
|
||||||
|
return detailsWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunConfiguration::updateEnabledState()
|
void RunConfiguration::updateEnabledState()
|
||||||
@@ -282,18 +287,6 @@ BuildConfiguration *RunConfiguration::activeBuildConfiguration() const
|
|||||||
return target()->activeBuildConfiguration();
|
return target()->activeBuildConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *RunConfiguration::wrapWidget(QWidget *inner) const
|
|
||||||
{
|
|
||||||
auto detailsWidget = new Utils::DetailsWidget;
|
|
||||||
detailsWidget->setState(DetailsWidget::NoSummary);
|
|
||||||
detailsWidget->setWidget(inner);
|
|
||||||
if (auto fl = qobject_cast<QFormLayout *>(inner->layout())){
|
|
||||||
fl->setMargin(0);
|
|
||||||
fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
|
||||||
}
|
|
||||||
return detailsWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
Target *RunConfiguration::target() const
|
Target *RunConfiguration::target() const
|
||||||
{
|
{
|
||||||
return static_cast<Target *>(parent());
|
return static_cast<Target *>(parent());
|
||||||
@@ -383,14 +376,14 @@ bool RunConfiguration::fromMap(const QVariantMap &map)
|
|||||||
Runnable RunConfiguration::runnable() const
|
Runnable RunConfiguration::runnable() const
|
||||||
{
|
{
|
||||||
Runnable r;
|
Runnable r;
|
||||||
if (auto aspect = extraAspect<ExecutableAspect>())
|
if (auto executableAspect = aspect<ExecutableAspect>())
|
||||||
r.executable = aspect->executable().toString();
|
r.executable = executableAspect->executable().toString();
|
||||||
if (auto aspect = extraAspect<ArgumentsAspect>())
|
if (auto argumentsAspect = aspect<ArgumentsAspect>())
|
||||||
r.commandLineArguments = aspect->arguments(macroExpander());
|
r.commandLineArguments = argumentsAspect->arguments(macroExpander());
|
||||||
if (auto aspect = extraAspect<WorkingDirectoryAspect>())
|
if (auto workingDirectoryAspect = aspect<WorkingDirectoryAspect>())
|
||||||
r.workingDirectory = aspect->workingDirectory(macroExpander()).toString();
|
r.workingDirectory = workingDirectoryAspect->workingDirectory(macroExpander()).toString();
|
||||||
if (auto aspect = extraAspect<EnvironmentAspect>())
|
if (auto environmentAspect = aspect<EnvironmentAspect>())
|
||||||
r.environment = aspect->environment();
|
r.environment = environmentAspect->environment();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1563,7 +1556,7 @@ SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl)
|
|||||||
m_runnable = runControl->runnable(); // Default value. Can be overridden using setRunnable.
|
m_runnable = runControl->runnable(); // Default value. Can be overridden using setRunnable.
|
||||||
m_device = runControl->device(); // Default value. Can be overridden using setDevice.
|
m_device = runControl->device(); // Default value. Can be overridden using setDevice.
|
||||||
if (auto runConfig = runControl->runConfiguration()) {
|
if (auto runConfig = runControl->runConfiguration()) {
|
||||||
if (auto terminalAspect = runConfig->extraAspect<TerminalAspect>())
|
if (auto terminalAspect = runConfig->aspect<TerminalAspect>())
|
||||||
m_useTerminal = terminalAspect->useTerminal();
|
m_useTerminal = terminalAspect->useTerminal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -185,8 +185,8 @@ public:
|
|||||||
|
|
||||||
template <class T = ISettingsAspect> T *currentSettings(Core::Id id) const
|
template <class T = ISettingsAspect> T *currentSettings(Core::Id id) const
|
||||||
{
|
{
|
||||||
if (auto aspect = qobject_cast<GlobalOrProjectAspect *>(extraAspect(id)))
|
if (auto a = qobject_cast<GlobalOrProjectAspect *>(aspect(id)))
|
||||||
return qobject_cast<T *>(aspect->currentSettings());
|
return qobject_cast<T *>(a->currentSettings());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,6 @@ protected:
|
|||||||
|
|
||||||
/// convenience function to get current build configuration.
|
/// convenience function to get current build configuration.
|
||||||
BuildConfiguration *activeBuildConfiguration() const;
|
BuildConfiguration *activeBuildConfiguration() const;
|
||||||
QWidget *wrapWidget(QWidget *inner) const;
|
|
||||||
|
|
||||||
template<class T> void setOutputFormatter()
|
template<class T> void setOutputFormatter()
|
||||||
{
|
{
|
||||||
|
@@ -113,6 +113,10 @@ public:
|
|||||||
|
|
||||||
bool showInSimpleTree() const override;
|
bool showInSimpleTree() const override;
|
||||||
QString addFileFilter() const override;
|
QString addFileFilter() const override;
|
||||||
|
bool supportsAction(ProjectAction action, const Node *node) const override;
|
||||||
|
bool addFiles(const QStringList &filePaths, QStringList *) override;
|
||||||
|
bool removeFiles(const QStringList &filePaths, QStringList *) override;
|
||||||
|
bool deleteFiles(const QStringList &) override;
|
||||||
bool renameFile(const QString &filePath, const QString &newFilePath) override;
|
bool renameFile(const QString &filePath, const QString &newFilePath) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -237,9 +241,9 @@ private:
|
|||||||
Runnable runnable() const final;
|
Runnable runnable() const final;
|
||||||
|
|
||||||
bool supportsDebugger() const { return true; }
|
bool supportsDebugger() const { return true; }
|
||||||
QString mainScript() const { return extraAspect<MainScriptAspect>()->value(); }
|
QString mainScript() const { return aspect<MainScriptAspect>()->value(); }
|
||||||
QString arguments() const { return extraAspect<ArgumentsAspect>()->arguments(macroExpander()); }
|
QString arguments() const { return aspect<ArgumentsAspect>()->arguments(macroExpander()); }
|
||||||
QString interpreter() const { return extraAspect<InterpreterAspect>()->value(); }
|
QString interpreter() const { return aspect<InterpreterAspect>()->value(); }
|
||||||
|
|
||||||
void updateTargetInformation();
|
void updateTargetInformation();
|
||||||
};
|
};
|
||||||
@@ -279,7 +283,7 @@ void PythonRunConfiguration::updateTargetInformation()
|
|||||||
const BuildTargetInfo bti = buildTargetInfo();
|
const BuildTargetInfo bti = buildTargetInfo();
|
||||||
const QString script = bti.targetFilePath.toString();
|
const QString script = bti.targetFilePath.toString();
|
||||||
setDefaultDisplayName(tr("Run %1").arg(script));
|
setDefaultDisplayName(tr("Run %1").arg(script));
|
||||||
extraAspect<MainScriptAspect>()->setValue(script);
|
aspect<MainScriptAspect>()->setValue(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
Runnable PythonRunConfiguration::runnable() const
|
Runnable PythonRunConfiguration::runnable() const
|
||||||
@@ -287,9 +291,9 @@ Runnable PythonRunConfiguration::runnable() const
|
|||||||
Runnable r;
|
Runnable r;
|
||||||
QtcProcess::addArg(&r.commandLineArguments, mainScript());
|
QtcProcess::addArg(&r.commandLineArguments, mainScript());
|
||||||
QtcProcess::addArgs(&r.commandLineArguments,
|
QtcProcess::addArgs(&r.commandLineArguments,
|
||||||
extraAspect<ArgumentsAspect>()->arguments(macroExpander()));
|
aspect<ArgumentsAspect>()->arguments(macroExpander()));
|
||||||
r.executable = extraAspect<InterpreterAspect>()->value();
|
r.executable = aspect<InterpreterAspect>()->value();
|
||||||
r.environment = extraAspect<EnvironmentAspect>()->environment();
|
r.environment = aspect<EnvironmentAspect>()->environment();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,11 +316,13 @@ PythonProject::PythonProject(const FileName &fileName) :
|
|||||||
setDisplayName(fileName.toFileInfo().completeBaseName());
|
setDisplayName(fileName.toFileInfo().completeBaseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
static QStringList readLines(const QString &absoluteFileName)
|
static QStringList readLines(const Utils::FileName &projectFile)
|
||||||
{
|
{
|
||||||
QStringList lines;
|
const QString projectFileName = projectFile.fileName();
|
||||||
|
QSet<QString> visited = { projectFileName };
|
||||||
|
QStringList lines = { projectFileName };
|
||||||
|
|
||||||
QFile file(absoluteFileName);
|
QFile file(projectFile.toString());
|
||||||
if (file.open(QFile::ReadOnly)) {
|
if (file.open(QFile::ReadOnly)) {
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
|
|
||||||
@@ -324,8 +330,10 @@ static QStringList readLines(const QString &absoluteFileName)
|
|||||||
QString line = stream.readLine();
|
QString line = stream.readLine();
|
||||||
if (line.isNull())
|
if (line.isNull())
|
||||||
break;
|
break;
|
||||||
|
if (visited.contains(line))
|
||||||
|
continue;
|
||||||
lines.append(line);
|
lines.append(line);
|
||||||
|
visited.insert(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,14 +370,6 @@ bool PythonProject::addFiles(const QStringList &filePaths)
|
|||||||
foreach (const QString &filePath, filePaths)
|
foreach (const QString &filePath, filePaths)
|
||||||
newList.append(baseDir.relativeFilePath(filePath));
|
newList.append(baseDir.relativeFilePath(filePath));
|
||||||
|
|
||||||
QSet<QString> toAdd;
|
|
||||||
|
|
||||||
foreach (const QString &filePath, filePaths) {
|
|
||||||
QString directory = QFileInfo(filePath).absolutePath();
|
|
||||||
if (!toAdd.contains(directory))
|
|
||||||
toAdd << directory;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool result = saveRawList(newList, projectFilePath().toString());
|
bool result = saveRawList(newList, projectFilePath().toString());
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@ bool PythonProject::removeFiles(const QStringList &filePaths)
|
|||||||
bool PythonProject::setFiles(const QStringList &filePaths)
|
bool PythonProject::setFiles(const QStringList &filePaths)
|
||||||
{
|
{
|
||||||
QStringList newList;
|
QStringList newList;
|
||||||
QDir baseDir(projectFilePath().toString());
|
QDir baseDir(projectDirectory().toString());
|
||||||
foreach (const QString &filePath, filePaths)
|
foreach (const QString &filePath, filePaths)
|
||||||
newList.append(baseDir.relativeFilePath(filePath));
|
newList.append(baseDir.relativeFilePath(filePath));
|
||||||
|
|
||||||
@@ -407,7 +407,7 @@ bool PythonProject::renameFile(const QString &filePath, const QString &newFilePa
|
|||||||
if (i != m_rawListEntries.end()) {
|
if (i != m_rawListEntries.end()) {
|
||||||
int index = newList.indexOf(i.value());
|
int index = newList.indexOf(i.value());
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
QDir baseDir(projectFilePath().toString());
|
QDir baseDir(projectDirectory().toString());
|
||||||
newList.replace(index, baseDir.relativeFilePath(newFilePath));
|
newList.replace(index, baseDir.relativeFilePath(newFilePath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -418,8 +418,7 @@ bool PythonProject::renameFile(const QString &filePath, const QString &newFilePa
|
|||||||
void PythonProject::parseProject()
|
void PythonProject::parseProject()
|
||||||
{
|
{
|
||||||
m_rawListEntries.clear();
|
m_rawListEntries.clear();
|
||||||
m_rawFileList = readLines(projectFilePath().toString());
|
m_rawFileList = readLines(projectFilePath());
|
||||||
m_rawFileList << projectFilePath().fileName();
|
|
||||||
m_files = processEntries(m_rawFileList, &m_rawListEntries);
|
m_files = processEntries(m_rawFileList, &m_rawListEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,6 +580,37 @@ QString PythonProjectNode::addFileFilter() const
|
|||||||
return QLatin1String("*.py");
|
return QLatin1String("*.py");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PythonProjectNode::supportsAction(ProjectAction action, const Node *node) const
|
||||||
|
{
|
||||||
|
switch (node->nodeType()) {
|
||||||
|
case NodeType::File:
|
||||||
|
return action == ProjectAction::Rename
|
||||||
|
|| action == ProjectAction::RemoveFile;
|
||||||
|
case NodeType::Folder:
|
||||||
|
case NodeType::Project:
|
||||||
|
return action == ProjectAction::AddNewFile
|
||||||
|
|| action == ProjectAction::RemoveFile
|
||||||
|
|| action == ProjectAction::AddExistingFile;
|
||||||
|
default:
|
||||||
|
return ProjectNode::supportsAction(action, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PythonProjectNode::addFiles(const QStringList &filePaths, QStringList *)
|
||||||
|
{
|
||||||
|
return m_project->addFiles(filePaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PythonProjectNode::removeFiles(const QStringList &filePaths, QStringList *)
|
||||||
|
{
|
||||||
|
return m_project->removeFiles(filePaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PythonProjectNode::deleteFiles(const QStringList &)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool PythonProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
|
bool PythonProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
|
||||||
{
|
{
|
||||||
return m_project->renameFile(filePath, newFilePath);
|
return m_project->renameFile(filePath, newFilePath);
|
||||||
|
@@ -30,11 +30,11 @@
|
|||||||
#include <projectexplorer/kitconfigwidget.h>
|
#include <projectexplorer/kitconfigwidget.h>
|
||||||
#include <projectexplorer/kitmanager.h>
|
#include <projectexplorer/kitmanager.h>
|
||||||
|
|
||||||
|
#include <utils/elidinglabel.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <qbs.h>
|
#include <qbs.h>
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
@@ -48,7 +48,7 @@ class ConfigWidget final : public KitConfigWidget
|
|||||||
public:
|
public:
|
||||||
ConfigWidget(Kit *kit, const KitInformation *kitInfo)
|
ConfigWidget(Kit *kit, const KitInformation *kitInfo)
|
||||||
: KitConfigWidget(kit, kitInfo),
|
: KitConfigWidget(kit, kitInfo),
|
||||||
m_contentLabel(new QLabel),
|
m_contentLabel(new Utils::ElidingLabel),
|
||||||
m_changeButton(new QPushButton(tr("Change...")))
|
m_changeButton(new QPushButton(tr("Change...")))
|
||||||
{
|
{
|
||||||
connect(m_changeButton, &QPushButton::clicked, this, &ConfigWidget::changeProperties);
|
connect(m_changeButton, &QPushButton::clicked, this, &ConfigWidget::changeProperties);
|
||||||
|
@@ -110,11 +110,11 @@ void QbsRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &
|
|||||||
|
|
||||||
void QbsRunConfiguration::addToBaseEnvironment(Utils::Environment &env) const
|
void QbsRunConfiguration::addToBaseEnvironment(Utils::Environment &env) const
|
||||||
{
|
{
|
||||||
if (auto dyldAspect = extraAspect<UseDyldSuffixAspect>()) {
|
if (auto dyldAspect = aspect<UseDyldSuffixAspect>()) {
|
||||||
if (dyldAspect->value())
|
if (dyldAspect->value())
|
||||||
env.set("DYLD_IMAGE_SUFFIX", "_debug");
|
env.set("DYLD_IMAGE_SUFFIX", "_debug");
|
||||||
}
|
}
|
||||||
bool usingLibraryPaths = extraAspect<UseLibraryPathsAspect>()->value();
|
bool usingLibraryPaths = aspect<UseLibraryPathsAspect>()->value();
|
||||||
|
|
||||||
const auto key = qMakePair(env.toStringList(), usingLibraryPaths);
|
const auto key = qMakePair(env.toStringList(), usingLibraryPaths);
|
||||||
const auto it = m_envCache.constFind(key);
|
const auto it = m_envCache.constFind(key);
|
||||||
@@ -146,16 +146,16 @@ void QbsRunConfiguration::updateTargetInformation()
|
|||||||
{
|
{
|
||||||
BuildTargetInfo bti = buildTargetInfo();
|
BuildTargetInfo bti = buildTargetInfo();
|
||||||
const FileName executable = executableToRun(bti);
|
const FileName executable = executableToRun(bti);
|
||||||
auto terminalAspect = extraAspect<TerminalAspect>();
|
auto terminalAspect = aspect<TerminalAspect>();
|
||||||
if (!terminalAspect->isUserSet())
|
if (!terminalAspect->isUserSet())
|
||||||
terminalAspect->setUseTerminal(bti.usesTerminal);
|
terminalAspect->setUseTerminal(bti.usesTerminal);
|
||||||
|
|
||||||
extraAspect<ExecutableAspect>()->setExecutable(executable);
|
aspect<ExecutableAspect>()->setExecutable(executable);
|
||||||
|
|
||||||
if (!executable.isEmpty()) {
|
if (!executable.isEmpty()) {
|
||||||
QString defaultWorkingDir = QFileInfo(executable.toString()).absolutePath();
|
QString defaultWorkingDir = QFileInfo(executable.toString()).absolutePath();
|
||||||
if (!defaultWorkingDir.isEmpty()) {
|
if (!defaultWorkingDir.isEmpty()) {
|
||||||
auto wdAspect = extraAspect<WorkingDirectoryAspect>();
|
auto wdAspect = aspect<WorkingDirectoryAspect>();
|
||||||
wdAspect->setDefaultWorkingDirectory(FileName::fromString(defaultWorkingDir));
|
wdAspect->setDefaultWorkingDirectory(FileName::fromString(defaultWorkingDir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -91,20 +91,20 @@ DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *target, Core:
|
|||||||
void DesktopQmakeRunConfiguration::updateTargetInformation()
|
void DesktopQmakeRunConfiguration::updateTargetInformation()
|
||||||
{
|
{
|
||||||
setDefaultDisplayName(defaultDisplayName());
|
setDefaultDisplayName(defaultDisplayName());
|
||||||
extraAspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged();
|
aspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged();
|
||||||
|
|
||||||
BuildTargetInfo bti = buildTargetInfo();
|
BuildTargetInfo bti = buildTargetInfo();
|
||||||
|
|
||||||
auto wda = extraAspect<WorkingDirectoryAspect>();
|
auto wda = aspect<WorkingDirectoryAspect>();
|
||||||
wda->setDefaultWorkingDirectory(bti.workingDirectory);
|
wda->setDefaultWorkingDirectory(bti.workingDirectory);
|
||||||
if (wda->pathChooser())
|
if (wda->pathChooser())
|
||||||
wda->pathChooser()->setBaseFileName(target()->project()->projectDirectory());
|
wda->pathChooser()->setBaseFileName(target()->project()->projectDirectory());
|
||||||
|
|
||||||
auto terminalAspect = extraAspect<TerminalAspect>();
|
auto terminalAspect = aspect<TerminalAspect>();
|
||||||
if (!terminalAspect->isUserSet())
|
if (!terminalAspect->isUserSet())
|
||||||
terminalAspect->setUseTerminal(bti.usesTerminal);
|
terminalAspect->setUseTerminal(bti.usesTerminal);
|
||||||
|
|
||||||
extraAspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
|
aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap DesktopQmakeRunConfiguration::toMap() const
|
QVariantMap DesktopQmakeRunConfiguration::toMap() const
|
||||||
@@ -135,9 +135,9 @@ void DesktopQmakeRunConfiguration::addToBaseEnvironment(Environment &env) const
|
|||||||
{
|
{
|
||||||
BuildTargetInfo bti = buildTargetInfo();
|
BuildTargetInfo bti = buildTargetInfo();
|
||||||
if (bti.runEnvModifier)
|
if (bti.runEnvModifier)
|
||||||
bti.runEnvModifier(env, extraAspect<UseLibraryPathsAspect>()->value());
|
bti.runEnvModifier(env, aspect<UseLibraryPathsAspect>()->value());
|
||||||
|
|
||||||
if (auto dyldAspect = extraAspect<UseDyldSuffixAspect>()) {
|
if (auto dyldAspect = aspect<UseDyldSuffixAspect>()) {
|
||||||
if (dyldAspect->value())
|
if (dyldAspect->value())
|
||||||
env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug"));
|
env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug"));
|
||||||
}
|
}
|
||||||
|
@@ -302,7 +302,7 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
|
|||||||
auto runConfiguration = runControl->runConfiguration();
|
auto runConfiguration = runControl->runConfiguration();
|
||||||
if (runConfiguration) {
|
if (runConfiguration) {
|
||||||
auto aspect = static_cast<QmlProfilerRunConfigurationAspect *>(
|
auto aspect = static_cast<QmlProfilerRunConfigurationAspect *>(
|
||||||
runConfiguration->extraAspect(Constants::SETTINGS));
|
runConfiguration->aspect(Constants::SETTINGS));
|
||||||
if (aspect) {
|
if (aspect) {
|
||||||
if (QmlProfilerSettings *settings = static_cast<QmlProfilerSettings *>(aspect->currentSettings())) {
|
if (QmlProfilerSettings *settings = static_cast<QmlProfilerSettings *>(aspect->currentSettings())) {
|
||||||
d->m_profilerConnections->setFlushInterval(settings->flushEnabled() ?
|
d->m_profilerConnections->setFlushInterval(settings->flushEnabled() ?
|
||||||
|
@@ -305,7 +305,7 @@ Runnable QmlProjectRunConfiguration::runnable() const
|
|||||||
Runnable r;
|
Runnable r;
|
||||||
r.executable = executable();
|
r.executable = executable();
|
||||||
r.commandLineArguments = commandLineArguments();
|
r.commandLineArguments = commandLineArguments();
|
||||||
r.environment = extraAspect<QmlProjectEnvironmentAspect>()->environment();
|
r.environment = aspect<QmlProjectEnvironmentAspect>()->environment();
|
||||||
r.workingDirectory = static_cast<QmlProject *>(project())->targetDirectory(target()).toString();
|
r.workingDirectory = static_cast<QmlProject *>(project())->targetDirectory(target()).toString();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -354,7 +354,7 @@ QString QmlProjectRunConfiguration::executable() const
|
|||||||
QString QmlProjectRunConfiguration::commandLineArguments() const
|
QString QmlProjectRunConfiguration::commandLineArguments() const
|
||||||
{
|
{
|
||||||
// arguments in .user file
|
// arguments in .user file
|
||||||
QString args = extraAspect<ArgumentsAspect>()->arguments(macroExpander());
|
QString args = aspect<ArgumentsAspect>()->arguments(macroExpander());
|
||||||
const Target *currentTarget = target();
|
const Target *currentTarget = target();
|
||||||
const IDevice::ConstPtr device = DeviceKitInformation::device(currentTarget->kit());
|
const IDevice::ConstPtr device = DeviceKitInformation::device(currentTarget->kit());
|
||||||
const Utils::OsType osType = device ? device->osType() : Utils::HostOsInfo::hostOs();
|
const Utils::OsType osType = device ? device->osType() : Utils::HostOsInfo::hostOs();
|
||||||
|
@@ -265,7 +265,7 @@ void QnxAttachDebugSupport::showProcessesDialog()
|
|||||||
// QString projectSourceDirectory = dlg.projectSource();
|
// QString projectSourceDirectory = dlg.projectSource();
|
||||||
QString localExecutable = dlg.localExecutable();
|
QString localExecutable = dlg.localExecutable();
|
||||||
if (localExecutable.isEmpty()) {
|
if (localExecutable.isEmpty()) {
|
||||||
if (auto aspect = runConfig->extraAspect<SymbolFileAspect>())
|
if (auto aspect = runConfig->aspect<SymbolFileAspect>())
|
||||||
localExecutable = aspect->fileName().toString();
|
localExecutable = aspect->fileName().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,7 +45,7 @@ QnxRunConfiguration::QnxRunConfiguration(Target *target, Core::Id id)
|
|||||||
Runnable QnxRunConfiguration::runnable() const
|
Runnable QnxRunConfiguration::runnable() const
|
||||||
{
|
{
|
||||||
Runnable r = RemoteLinuxRunConfiguration::runnable();
|
Runnable r = RemoteLinuxRunConfiguration::runnable();
|
||||||
QString libPath = extraAspect<QtLibPathAspect>()->value();
|
QString libPath = aspect<QtLibPathAspect>()->value();
|
||||||
if (!libPath.isEmpty()) {
|
if (!libPath.isEmpty()) {
|
||||||
r.environment.appendOrSet("LD_LIBRARY_PATH", libPath + "/lib:$LD_LIBRARY_PATH");
|
r.environment.appendOrSet("LD_LIBRARY_PATH", libPath + "/lib:$LD_LIBRARY_PATH");
|
||||||
r.environment.appendOrSet("QML_IMPORT_PATH", libPath + "/imports:$QML_IMPORT_PATH");
|
r.environment.appendOrSet("QML_IMPORT_PATH", libPath + "/imports:$QML_IMPORT_PATH");
|
||||||
|
@@ -45,7 +45,7 @@ Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl)
|
|||||||
: RunWorker(runControl)
|
: RunWorker(runControl)
|
||||||
{
|
{
|
||||||
setId("Slog2InfoRunner");
|
setId("Slog2InfoRunner");
|
||||||
m_applicationId = runControl->runConfiguration()->extraAspect<ExecutableAspect>()->executable().fileName();
|
m_applicationId = runControl->runConfiguration()->aspect<ExecutableAspect>()->executable().fileName();
|
||||||
|
|
||||||
// See QTCREATORBUG-10712 for details.
|
// See QTCREATORBUG-10712 for details.
|
||||||
// We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info.
|
// We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info.
|
||||||
|
@@ -65,7 +65,7 @@ RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(Target *tar
|
|||||||
|
|
||||||
bool RemoteLinuxCustomRunConfiguration::isConfigured() const
|
bool RemoteLinuxCustomRunConfiguration::isConfigured() const
|
||||||
{
|
{
|
||||||
return !extraAspect<ExecutableAspect>()->executable().isEmpty();
|
return !aspect<ExecutableAspect>()->executable().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
RunConfiguration::ConfigurationState
|
RunConfiguration::ConfigurationState
|
||||||
@@ -88,7 +88,7 @@ Core::Id RemoteLinuxCustomRunConfiguration::runConfigId()
|
|||||||
|
|
||||||
QString RemoteLinuxCustomRunConfiguration::runConfigDefaultDisplayName()
|
QString RemoteLinuxCustomRunConfiguration::runConfigDefaultDisplayName()
|
||||||
{
|
{
|
||||||
QString remoteExecutable = extraAspect<ExecutableAspect>()->executable().toString();
|
QString remoteExecutable = aspect<ExecutableAspect>()->executable().toString();
|
||||||
QString display = remoteExecutable.isEmpty()
|
QString display = remoteExecutable.isEmpty()
|
||||||
? tr("Custom Executable") : tr("Run \"%1\"").arg(remoteExecutable);
|
? tr("Custom Executable") : tr("Run \"%1\"").arg(remoteExecutable);
|
||||||
return RunConfigurationFactory::decoratedTargetName(display, target());
|
return RunConfigurationFactory::decoratedTargetName(display, target());
|
||||||
|
@@ -73,24 +73,14 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Core::I
|
|||||||
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
|
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &)
|
|
||||||
{
|
|
||||||
setDefaultDisplayName(defaultDisplayName());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RemoteLinuxRunConfiguration::defaultDisplayName() const
|
|
||||||
{
|
|
||||||
return RunConfigurationFactory::decoratedTargetName(buildKey(), target());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoteLinuxRunConfiguration::updateTargetInformation()
|
void RemoteLinuxRunConfiguration::updateTargetInformation()
|
||||||
{
|
{
|
||||||
BuildTargetInfo bti = buildTargetInfo();
|
BuildTargetInfo bti = buildTargetInfo();
|
||||||
QString localExecutable = bti.targetFilePath.toString();
|
QString localExecutable = bti.targetFilePath.toString();
|
||||||
DeployableFile depFile = target()->deploymentData().deployableForLocalFile(localExecutable);
|
DeployableFile depFile = target()->deploymentData().deployableForLocalFile(localExecutable);
|
||||||
|
|
||||||
extraAspect<ExecutableAspect>()->setExecutable(FileName::fromString(depFile.remoteFilePath()));
|
aspect<ExecutableAspect>()->setExecutable(FileName::fromString(depFile.remoteFilePath()));
|
||||||
extraAspect<SymbolFileAspect>()->setValue(localExecutable);
|
aspect<SymbolFileAspect>()->setValue(localExecutable);
|
||||||
|
|
||||||
emit enabledChanged();
|
emit enabledChanged();
|
||||||
}
|
}
|
||||||
@@ -103,6 +93,7 @@ const char *RemoteLinuxRunConfiguration::IdPrefix = "RemoteLinuxRunConfiguration
|
|||||||
RemoteLinuxRunConfigurationFactory::RemoteLinuxRunConfigurationFactory()
|
RemoteLinuxRunConfigurationFactory::RemoteLinuxRunConfigurationFactory()
|
||||||
{
|
{
|
||||||
registerRunConfiguration<RemoteLinuxRunConfiguration>(RemoteLinuxRunConfiguration::IdPrefix);
|
registerRunConfiguration<RemoteLinuxRunConfiguration>(RemoteLinuxRunConfiguration::IdPrefix);
|
||||||
|
setDecorateDisplayNames(true);
|
||||||
addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType);
|
addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,9 +40,6 @@ public:
|
|||||||
static const char *IdPrefix;
|
static const char *IdPrefix;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &) override;
|
|
||||||
|
|
||||||
QString defaultDisplayName() const;
|
|
||||||
void updateTargetInformation();
|
void updateTargetInformation();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -31,9 +31,11 @@
|
|||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
#include <texteditor/completionsettings.h>
|
#include <texteditor/completionsettings.h>
|
||||||
#include <texteditor/texteditorconstants.h>
|
#include <texteditor/texteditorconstants.h>
|
||||||
|
#include <texteditor/codeassist/assistproposaliteminterface.h>
|
||||||
|
|
||||||
#include <utils/faketooltip.h>
|
#include <utils/faketooltip.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QLatin1String>
|
#include <QLatin1String>
|
||||||
@@ -49,6 +51,7 @@
|
|||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
@@ -92,6 +95,8 @@ QVariant ModelAdapter::data(const QModelIndex &index, int role) const
|
|||||||
return m_completionModel->icon(index.row());
|
return m_completionModel->icon(index.row());
|
||||||
else if (role == Qt::WhatsThisRole)
|
else if (role == Qt::WhatsThisRole)
|
||||||
return m_completionModel->detail(index.row());
|
return m_completionModel->detail(index.row());
|
||||||
|
else if (role == Qt::UserRole)
|
||||||
|
return m_completionModel->proposalItem(index.row())->requiresFixIts();
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@@ -146,6 +151,7 @@ private:
|
|||||||
// -----------------------
|
// -----------------------
|
||||||
class GenericProposalListView : public QListView
|
class GenericProposalListView : public QListView
|
||||||
{
|
{
|
||||||
|
friend class ProposalItemDelegate;
|
||||||
public:
|
public:
|
||||||
GenericProposalListView(QWidget *parent);
|
GenericProposalListView(QWidget *parent);
|
||||||
|
|
||||||
@@ -160,10 +166,53 @@ public:
|
|||||||
void selectLastRow() { selectRow(model()->rowCount() - 1); }
|
void selectLastRow() { selectRow(model()->rowCount() - 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ProposalItemDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ProposalItemDelegate(GenericProposalListView *parent = nullptr)
|
||||||
|
: QStyledItemDelegate(parent)
|
||||||
|
, m_parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const override
|
||||||
|
{
|
||||||
|
static const QIcon fixItIcon = ::Utils::Icons::CODEMODEL_FIXIT.icon();
|
||||||
|
|
||||||
|
QStyledItemDelegate::paint(painter, option, index);
|
||||||
|
|
||||||
|
if (m_parent->model()->data(index, Qt::UserRole).toBool()) {
|
||||||
|
const QRect itemRect = m_parent->rectForIndex(index);
|
||||||
|
const QScrollBar *verticalScrollBar = m_parent->verticalScrollBar();
|
||||||
|
|
||||||
|
const int x = m_parent->width() - itemRect.height() - (verticalScrollBar->isVisible()
|
||||||
|
? verticalScrollBar->width()
|
||||||
|
: 0);
|
||||||
|
const int iconSize = itemRect.height() - 5;
|
||||||
|
fixItIcon.paint(painter, QRect(x, itemRect.y() - m_parent->verticalOffset(),
|
||||||
|
iconSize, iconSize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
|
||||||
|
{
|
||||||
|
QSize size(QStyledItemDelegate::sizeHint(option, index));
|
||||||
|
if (m_parent->model()->data(index, Qt::UserRole).toBool())
|
||||||
|
size.setWidth(size.width() + m_parent->rectForIndex(index).height() - 5);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
GenericProposalListView *m_parent;
|
||||||
|
};
|
||||||
|
|
||||||
GenericProposalListView::GenericProposalListView(QWidget *parent)
|
GenericProposalListView::GenericProposalListView(QWidget *parent)
|
||||||
: QListView(parent)
|
: QListView(parent)
|
||||||
{
|
{
|
||||||
setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
||||||
|
setItemDelegate(new ProposalItemDelegate(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize GenericProposalListView::calculateSize() const
|
QSize GenericProposalListView::calculateSize() const
|
||||||
|
@@ -86,7 +86,7 @@ void ValgrindToolRunner::start()
|
|||||||
m_runner.setDevice(device());
|
m_runner.setDevice(device());
|
||||||
m_runner.setDebuggee(runnable());
|
m_runner.setDebuggee(runnable());
|
||||||
|
|
||||||
if (auto aspect = runControl()->runConfiguration()->extraAspect<TerminalAspect>())
|
if (auto aspect = runControl()->runConfiguration()->aspect<TerminalAspect>())
|
||||||
m_runner.setUseTerminal(aspect->useTerminal());
|
m_runner.setUseTerminal(aspect->useTerminal());
|
||||||
|
|
||||||
connect(&m_runner, &ValgrindRunner::processOutputReceived,
|
connect(&m_runner, &ValgrindRunner::processOutputReceived,
|
||||||
|
@@ -84,13 +84,13 @@ WinRtRunnerHelper::WinRtRunnerHelper(ProjectExplorer::RunWorker *runWorker, QStr
|
|||||||
|
|
||||||
bool loopbackExemptClient = false;
|
bool loopbackExemptClient = false;
|
||||||
bool loopbackExemptServer = false;
|
bool loopbackExemptServer = false;
|
||||||
if (auto aspect = runConfiguration->extraAspect<ArgumentsAspect>())
|
if (auto aspect = runConfiguration->aspect<ArgumentsAspect>())
|
||||||
m_arguments = aspect->arguments(runConfiguration->macroExpander());
|
m_arguments = aspect->arguments(runConfiguration->macroExpander());
|
||||||
if (auto aspect = runConfiguration->extraAspect<UninstallAfterStopAspect>())
|
if (auto aspect = runConfiguration->aspect<UninstallAfterStopAspect>())
|
||||||
m_uninstallAfterStop = aspect->value();
|
m_uninstallAfterStop = aspect->value();
|
||||||
if (auto aspect = runConfiguration->extraAspect<LoopbackExemptClientAspect>())
|
if (auto aspect = runConfiguration->aspect<LoopbackExemptClientAspect>())
|
||||||
loopbackExemptClient = aspect->value();
|
loopbackExemptClient = aspect->value();
|
||||||
if (auto aspect = runConfiguration->extraAspect<LoopbackExemptServerAspect>())
|
if (auto aspect = runConfiguration->aspect<LoopbackExemptServerAspect>())
|
||||||
loopbackExemptServer = aspect->value();
|
loopbackExemptServer = aspect->value();
|
||||||
if (loopbackExemptClient && loopbackExemptServer)
|
if (loopbackExemptClient && loopbackExemptServer)
|
||||||
m_loopbackArguments = "--loopbackexempt clientserver";
|
m_loopbackArguments = "--loopbackexempt clientserver";
|
||||||
|
@@ -40,6 +40,8 @@
|
|||||||
#include "unsavedfile.h"
|
#include "unsavedfile.h"
|
||||||
#include "unsavedfiles.h"
|
#include "unsavedfiles.h"
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <clang-c/Index.h>
|
#include <clang-c/Index.h>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
@@ -47,13 +49,14 @@ namespace ClangBackEnd {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
CodeCompletions toCodeCompletions(const TranslationUnit &translationUnit,
|
CodeCompletions toCodeCompletions(const TranslationUnit &translationUnit,
|
||||||
const ClangCodeCompleteResults &results)
|
const ClangCodeCompleteResults &results,
|
||||||
|
bool onlyFunctionOverloads)
|
||||||
{
|
{
|
||||||
if (results.isNull())
|
if (results.isNull())
|
||||||
return CodeCompletions();
|
return CodeCompletions();
|
||||||
|
|
||||||
CodeCompletionsExtractor extractor(translationUnit.cxTranslationUnit(), results.data());
|
CodeCompletionsExtractor extractor(translationUnit.cxTranslationUnit(), results.data());
|
||||||
CodeCompletions codeCompletions = extractor.extractAll();
|
CodeCompletions codeCompletions = extractor.extractAll(onlyFunctionOverloads);
|
||||||
|
|
||||||
return codeCompletions;
|
return codeCompletions;
|
||||||
}
|
}
|
||||||
@@ -83,33 +86,49 @@ CodeCompleter::CodeCompleter(const TranslationUnit &translationUnit,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void replaceWithOpeningParen(UnsavedFile &file, uint line, uint column)
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
const uint pos = file.toUtf8Position(line, column, &ok);
|
||||||
|
QTC_ASSERT(ok, return;);
|
||||||
|
file.replaceAt(pos, 1, Utf8String("(", 1));
|
||||||
|
}
|
||||||
|
|
||||||
CodeCompletions CodeCompleter::complete(uint line, uint column,
|
CodeCompletions CodeCompleter::complete(uint line, uint column,
|
||||||
int funcNameStartLine,
|
int funcNameStartLine,
|
||||||
int funcNameStartColumn)
|
int funcNameStartColumn)
|
||||||
{
|
{
|
||||||
|
if (funcNameStartLine >= 0) {
|
||||||
|
UnsavedFile &file = unsavedFiles.unsavedFile(translationUnit.filePath());
|
||||||
|
// Replace '{' by '(' to get proper FunctionOverloadCompletionKind for constructor.
|
||||||
|
if (file.hasCharacterAt(line, column - 1, '{'))
|
||||||
|
replaceWithOpeningParen(file, line, column - 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we have a smart pointer completion and get proper constructor signatures in results.
|
// Check if we have a smart pointer completion and get proper constructor signatures in results.
|
||||||
// Results are empty when it's not a smart pointer or this completion failed.
|
// Results are empty when it's not a smart pointer or this completion failed.
|
||||||
ClangCodeCompleteResults results = completeSmartPointerCreation(line,
|
ClangCodeCompleteResults clangCompletions = completeSmartPointerCreation(line,
|
||||||
column,
|
column,
|
||||||
funcNameStartLine,
|
funcNameStartLine,
|
||||||
funcNameStartColumn);
|
funcNameStartColumn);
|
||||||
|
|
||||||
if (results.isNull() || results.isEmpty())
|
// Default completion.
|
||||||
results = completeHelper(line, column);
|
if (clangCompletions.isNull() || clangCompletions.isEmpty())
|
||||||
|
clangCompletions = completeHelper(line, column);
|
||||||
|
|
||||||
filterUnknownContextResults(results, unsavedFile(), line, column);
|
filterUnknownContextResults(clangCompletions, unsavedFile(), line, column);
|
||||||
|
|
||||||
return toCodeCompletions(translationUnit, results);
|
return toCodeCompletions(translationUnit, clangCompletions, funcNameStartLine >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For given "make_unique<T>" / "make_shared<T>" / "QSharedPointer<T>::create" return "new T("
|
// For given "make_unique<T>" / "make_shared<T>" / "QSharedPointer<T>::create" return "new T("
|
||||||
// Otherwize return empty QString
|
// Otherwize return empty QString
|
||||||
static QString tweakName(const QString &oldName)
|
static QString tweakName(const Utf8String &oldName)
|
||||||
{
|
{
|
||||||
QString fullName = oldName.trimmed();
|
if (!oldName.contains('>'))
|
||||||
if (!fullName.contains('>'))
|
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
|
QString fullName = QString(oldName).trimmed();
|
||||||
if (!fullName.endsWith('>')) {
|
if (!fullName.endsWith('>')) {
|
||||||
// This is the class<type>::method case - remove ::method part
|
// This is the class<type>::method case - remove ::method part
|
||||||
if (!fullName.endsWith("create") || !fullName.contains("QSharedPointer"))
|
if (!fullName.endsWith("create") || !fullName.contains("QSharedPointer"))
|
||||||
@@ -138,10 +157,12 @@ ClangCodeCompleteResults CodeCompleter::completeSmartPointerCreation(uint line,
|
|||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
const uint startPos = file.toUtf8Position(funcNameStartLine, funcNameStartColumn, &ok);
|
const uint startPos = file.toUtf8Position(funcNameStartLine, funcNameStartColumn, &ok);
|
||||||
|
QTC_ASSERT(ok, return ClangCodeCompleteResults(););
|
||||||
const uint endPos = file.toUtf8Position(line, column - 1, &ok);
|
const uint endPos = file.toUtf8Position(line, column - 1, &ok);
|
||||||
|
QTC_ASSERT(ok, return ClangCodeCompleteResults(););
|
||||||
|
|
||||||
Utf8String content = file.fileContent();
|
const Utf8String content = file.fileContent();
|
||||||
const QString oldName = content.mid(startPos, endPos - startPos);
|
const Utf8String oldName = content.mid(startPos, endPos - startPos);
|
||||||
const QString updatedName = tweakName(oldName);
|
const QString updatedName = tweakName(oldName);
|
||||||
if (updatedName.isEmpty())
|
if (updatedName.isEmpty())
|
||||||
return ClangCodeCompleteResults();
|
return ClangCodeCompleteResults();
|
||||||
|
@@ -27,9 +27,13 @@
|
|||||||
|
|
||||||
#include "clangbackend_global.h"
|
#include "clangbackend_global.h"
|
||||||
#include "clangstring.h"
|
#include "clangstring.h"
|
||||||
|
#include "clangtranslationunit.h"
|
||||||
#include "codecompletionchunkconverter.h"
|
#include "codecompletionchunkconverter.h"
|
||||||
|
#include "sourcelocation.h"
|
||||||
#include "sourcerange.h"
|
#include "sourcerange.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
@@ -85,7 +89,7 @@ bool CodeCompletionsExtractor::peek(const Utf8String &name)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeCompletions CodeCompletionsExtractor::extractAll()
|
CodeCompletions CodeCompletionsExtractor::extractAll(bool onlyFunctionOverloads)
|
||||||
{
|
{
|
||||||
CodeCompletions codeCompletions;
|
CodeCompletions codeCompletions;
|
||||||
codeCompletions.reserve(int(cxCodeCompleteResults->NumResults));
|
codeCompletions.reserve(int(cxCodeCompleteResults->NumResults));
|
||||||
@@ -93,9 +97,75 @@ CodeCompletions CodeCompletionsExtractor::extractAll()
|
|||||||
while (next())
|
while (next())
|
||||||
codeCompletions.append(currentCodeCompletion_);
|
codeCompletions.append(currentCodeCompletion_);
|
||||||
|
|
||||||
|
handleCompletions(codeCompletions, onlyFunctionOverloads);
|
||||||
|
|
||||||
return codeCompletions;
|
return codeCompletions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CodeCompletions filterFunctionOverloads(const CodeCompletions &completions)
|
||||||
|
{
|
||||||
|
return ::Utils::filtered(completions, [](const CodeCompletion &completion) {
|
||||||
|
return completion.completionKind == CodeCompletion::FunctionOverloadCompletionKind;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static ::Utils::optional<bool> classBeforeCXXConstructor(const CodeCompletion &first,
|
||||||
|
const CodeCompletion &second)
|
||||||
|
{
|
||||||
|
// Put ClassCompletionKind elements before ConstructorCompletionKind elements
|
||||||
|
// when they have the same name.
|
||||||
|
if (first.completionKind == CodeCompletion::ClassCompletionKind
|
||||||
|
&& second.completionKind == CodeCompletion::ConstructorCompletionKind
|
||||||
|
&& first.text == second.text) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first.completionKind == CodeCompletion::ConstructorCompletionKind
|
||||||
|
&& second.completionKind == CodeCompletion::ClassCompletionKind
|
||||||
|
&& first.text == second.text) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ::Utils::optional<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sortCodeCompletions(CodeCompletions &codeCompletions)
|
||||||
|
{
|
||||||
|
auto currentItemsCompare = [](const CodeCompletion &first,
|
||||||
|
const CodeCompletion &second) {
|
||||||
|
// Items without fix-its come first.
|
||||||
|
if (first.requiredFixIts.empty() != second.requiredFixIts.empty())
|
||||||
|
return first.requiredFixIts.empty() > second.requiredFixIts.empty();
|
||||||
|
|
||||||
|
const ::Utils::optional<bool> classBeforeConstructorWithTheSameName
|
||||||
|
= classBeforeCXXConstructor(first, second);
|
||||||
|
if (classBeforeConstructorWithTheSameName)
|
||||||
|
return classBeforeConstructorWithTheSameName.value();
|
||||||
|
|
||||||
|
return (first.priority > 0
|
||||||
|
&& (first.priority < second.priority
|
||||||
|
|| (first.priority == second.priority && first.text < second.text)));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keep the order for the items with the same priority and name.
|
||||||
|
std::stable_sort(codeCompletions.begin(), codeCompletions.end(), currentItemsCompare);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeCompletionsExtractor::handleCompletions(CodeCompletions &codeCompletions,
|
||||||
|
bool onlyFunctionOverloads)
|
||||||
|
{
|
||||||
|
if (onlyFunctionOverloads) {
|
||||||
|
const CodeCompletions overloadCompletions = filterFunctionOverloads(codeCompletions);
|
||||||
|
|
||||||
|
// If filtered completions are empty the assumption we need function overloads is wrong
|
||||||
|
// therefore we do not use filtered results in that case.
|
||||||
|
if (!overloadCompletions.isEmpty())
|
||||||
|
codeCompletions = overloadCompletions;
|
||||||
|
}
|
||||||
|
|
||||||
|
sortCodeCompletions(codeCompletions);
|
||||||
|
}
|
||||||
|
|
||||||
void CodeCompletionsExtractor::extractCompletionKind()
|
void CodeCompletionsExtractor::extractCompletionKind()
|
||||||
{
|
{
|
||||||
switch (currentCxCodeCompleteResult.CursorKind) {
|
switch (currentCxCodeCompleteResult.CursorKind) {
|
||||||
|
@@ -50,7 +50,7 @@ public:
|
|||||||
bool next();
|
bool next();
|
||||||
bool peek(const Utf8String &name);
|
bool peek(const Utf8String &name);
|
||||||
|
|
||||||
CodeCompletions extractAll();
|
CodeCompletions extractAll(bool onlyFunctionOverloads);
|
||||||
|
|
||||||
const CodeCompletion ¤tCodeCompletion() const;
|
const CodeCompletion ¤tCodeCompletion() const;
|
||||||
|
|
||||||
@@ -73,6 +73,8 @@ private:
|
|||||||
void decreasePriorityForQObjectInternals();
|
void decreasePriorityForQObjectInternals();
|
||||||
void decreasePriorityForOperators();
|
void decreasePriorityForOperators();
|
||||||
|
|
||||||
|
void handleCompletions(CodeCompletions &codeCompletions, bool onlyFunctionOverloads);
|
||||||
|
|
||||||
bool hasText(const Utf8String &text, CXCompletionString cxCompletionString) const;
|
bool hasText(const Utf8String &text, CXCompletionString cxCompletionString) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -43,6 +43,7 @@ using ::testing::Not;
|
|||||||
using ::testing::PrintToString;
|
using ::testing::PrintToString;
|
||||||
|
|
||||||
using ClangBackEnd::CodeCompletion;
|
using ClangBackEnd::CodeCompletion;
|
||||||
|
using ClangBackEnd::CodeCompletionChunk;
|
||||||
using ClangBackEnd::CodeCompleter;
|
using ClangBackEnd::CodeCompleter;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -65,6 +66,29 @@ MATCHER_P2(IsCodeCompletion, text, completionKind,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MATCHER_P(IsOverloadCompletion, text,
|
||||||
|
std::string(negation ? "isn't" : "is") + " overload completion with text " + PrintToString(text))
|
||||||
|
{
|
||||||
|
Utf8String overloadName;
|
||||||
|
for (auto &chunk : arg.chunks) {
|
||||||
|
if (chunk.kind == CodeCompletionChunk::Text) {
|
||||||
|
overloadName = chunk.text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (overloadName != text) {
|
||||||
|
*result_listener << "text is " + PrintToString(overloadName) + " and not " + PrintToString(text);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg.completionKind != CodeCompletion::FunctionOverloadCompletionKind) {
|
||||||
|
*result_listener << "kind is " + PrintToString(arg.completionKind) + " and not " + PrintToString(CodeCompletion::FunctionOverloadCompletionKind);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
MATCHER(HasFixIts, "")
|
MATCHER(HasFixIts, "")
|
||||||
{
|
{
|
||||||
return !arg.requiredFixIts.empty();
|
return !arg.requiredFixIts.empty();
|
||||||
@@ -195,6 +219,12 @@ protected:
|
|||||||
readFileContent("/complete_smartpointer.cpp"),
|
readFileContent("/complete_smartpointer.cpp"),
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
|
ClangBackEnd::FileContainer completionsOrder{
|
||||||
|
Utf8StringLiteral(TESTDATA_DIR"/completions_order.cpp"),
|
||||||
|
{includePathArgument},
|
||||||
|
readFileContent("/completions_order.cpp"),
|
||||||
|
true
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
using CodeCompleterSlowTest = CodeCompleter;
|
using CodeCompleterSlowTest = CodeCompleter;
|
||||||
@@ -306,27 +336,24 @@ TEST_F(CodeCompleterSlowTest, UniquePointerCompletion)
|
|||||||
{
|
{
|
||||||
auto myCompleter = setupCompleter(smartPointerCompletion);
|
auto myCompleter = setupCompleter(smartPointerCompletion);
|
||||||
|
|
||||||
ASSERT_THAT(myCompleter.complete(55, 54, 55, 32),
|
ASSERT_THAT(myCompleter.complete(59, 54, 59, 32),
|
||||||
Contains(IsCodeCompletion(Utf8StringLiteral("Bar"),
|
Contains(IsOverloadCompletion(Utf8StringLiteral("Bar"))));
|
||||||
CodeCompletion::ConstructorCompletionKind)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CodeCompleterSlowTest, SharedPointerCompletion)
|
TEST_F(CodeCompleterSlowTest, SharedPointerCompletion)
|
||||||
{
|
{
|
||||||
auto myCompleter = setupCompleter(smartPointerCompletion);
|
auto myCompleter = setupCompleter(smartPointerCompletion);
|
||||||
|
|
||||||
ASSERT_THAT(myCompleter.complete(56, 55, 56, 33),
|
ASSERT_THAT(myCompleter.complete(60, 55, 60, 33),
|
||||||
Contains(IsCodeCompletion(Utf8StringLiteral("Bar"),
|
Contains(IsOverloadCompletion(Utf8StringLiteral("Bar"))));
|
||||||
CodeCompletion::ConstructorCompletionKind)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CodeCompleterSlowTest, QSharedPointerCompletion)
|
TEST_F(CodeCompleterSlowTest, QSharedPointerCompletion)
|
||||||
{
|
{
|
||||||
auto myCompleter = setupCompleter(smartPointerCompletion);
|
auto myCompleter = setupCompleter(smartPointerCompletion);
|
||||||
|
|
||||||
ASSERT_THAT(myCompleter.complete(57, 60, 57, 32),
|
ASSERT_THAT(myCompleter.complete(61, 60, 61, 32),
|
||||||
Contains(IsCodeCompletion(Utf8StringLiteral("Bar"),
|
Contains(IsOverloadCompletion(Utf8StringLiteral("Bar"))));
|
||||||
CodeCompletion::ConstructorCompletionKind)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CodeCompleterSlowTest, FunctionInUnsavedIncludedHeader)
|
TEST_F(CodeCompleterSlowTest, FunctionInUnsavedIncludedHeader)
|
||||||
@@ -499,6 +526,60 @@ TEST_F(CodeCompleterSlowTest, GlobalCompletionAfterForwardDeclaredClassPointer)
|
|||||||
ASSERT_TRUE(!completions.isEmpty());
|
ASSERT_TRUE(!completions.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CodeCompleterSlowTest, ConstructorCompletionExists)
|
||||||
|
{
|
||||||
|
auto myCompleter = setupCompleter(completionsOrder);
|
||||||
|
const ClangBackEnd::CodeCompletions completions = myCompleter.complete(8, 1);
|
||||||
|
|
||||||
|
int constructorIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) {
|
||||||
|
return codeCompletion.text == "Constructor" && codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_THAT(constructorIndex != -1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CodeCompleterSlowTest, ClassConstructorCompletionsOrder)
|
||||||
|
{
|
||||||
|
auto myCompleter = setupCompleter(completionsOrder);
|
||||||
|
const ClangBackEnd::CodeCompletions completions = myCompleter.complete(8, 1);
|
||||||
|
|
||||||
|
int classIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) {
|
||||||
|
return codeCompletion.text == "Constructor" && codeCompletion.completionKind == CodeCompletion::ClassCompletionKind;
|
||||||
|
});
|
||||||
|
int constructorIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) {
|
||||||
|
return codeCompletion.text == "Constructor" && codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_THAT(classIndex < constructorIndex, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CodeCompleterSlowTest, SharedPointerCompletionsOrder)
|
||||||
|
{
|
||||||
|
auto myCompleter = setupCompleter(smartPointerCompletion);
|
||||||
|
const ClangBackEnd::CodeCompletions completions = myCompleter.complete(62, 11);
|
||||||
|
|
||||||
|
int resetIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) {
|
||||||
|
return codeCompletion.text == "reset";
|
||||||
|
});
|
||||||
|
int barDestructorIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) {
|
||||||
|
return codeCompletion.text == "~Bar";
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_THAT(barDestructorIndex < resetIndex, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CodeCompleterSlowTest, ConstructorHasOverloadCompletions)
|
||||||
|
{
|
||||||
|
auto myCompleter = setupCompleter(completionsOrder);
|
||||||
|
const ClangBackEnd::CodeCompletions completions = myCompleter.complete(8, 1);
|
||||||
|
|
||||||
|
int constructorsCount = Utils::count(completions, [](const CodeCompletion &codeCompletion) {
|
||||||
|
return codeCompletion.text == "Constructor" && codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_THAT(constructorsCount, 2);
|
||||||
|
}
|
||||||
|
|
||||||
ClangBackEnd::CodeCompleter CodeCompleter::setupCompleter(
|
ClangBackEnd::CodeCompleter CodeCompleter::setupCompleter(
|
||||||
const ClangBackEnd::FileContainer &fileContainer)
|
const ClangBackEnd::FileContainer &fileContainer)
|
||||||
{
|
{
|
||||||
|
@@ -794,6 +794,18 @@ TEST_F(CodeCompletionsExtractorSlowTest, OverloadCandidate)
|
|||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CodeCompletionsExtractorSlowTest, ExtractAll)
|
||||||
|
{
|
||||||
|
ClangCodeCompleteResults completeResults(getResults(constructorDocument, 25));
|
||||||
|
::CodeCompletionsExtractor extractor(
|
||||||
|
constructorDocument.translationUnit().cxTranslationUnit(),
|
||||||
|
completeResults.data());
|
||||||
|
|
||||||
|
auto codeCompletions = extractor.extractAll(false);
|
||||||
|
|
||||||
|
ASSERT_THAT(codeCompletions.empty(), false);
|
||||||
|
}
|
||||||
|
|
||||||
ClangCodeCompleteResults CodeCompletionsExtractor::getResults(const Document &document,
|
ClangCodeCompleteResults CodeCompletionsExtractor::getResults(const Document &document,
|
||||||
uint line,
|
uint line,
|
||||||
uint column,
|
uint column,
|
||||||
|
@@ -27,7 +27,11 @@ template<class Type, class... Args>
|
|||||||
class unique_ptr {};
|
class unique_ptr {};
|
||||||
|
|
||||||
template<class Type, class... Args>
|
template<class Type, class... Args>
|
||||||
class shared_ptr {};
|
class shared_ptr {
|
||||||
|
public:
|
||||||
|
void reset();
|
||||||
|
Type *operator->();
|
||||||
|
};
|
||||||
|
|
||||||
template<class Type, class... Args>
|
template<class Type, class... Args>
|
||||||
unique_ptr<Type> make_unique(Args&&... args);
|
unique_ptr<Type> make_unique(Args&&... args);
|
||||||
@@ -55,4 +59,5 @@ void f2()
|
|||||||
std::unique_ptr<Bar> bar = std::make_unique<Bar>();
|
std::unique_ptr<Bar> bar = std::make_unique<Bar>();
|
||||||
std::shared_ptr<Bar> bar2 = std::make_shared<Bar>();
|
std::shared_ptr<Bar> bar2 = std::make_shared<Bar>();
|
||||||
QSharedPointer<Bar> bar3 = QSharedPointer<Bar>::create();
|
QSharedPointer<Bar> bar3 = QSharedPointer<Bar>::create();
|
||||||
|
bar2->
|
||||||
}
|
}
|
||||||
|
9
tests/unit/unittest/data/completions_order.cpp
Normal file
9
tests/unit/unittest/data/completions_order.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class Constructor {
|
||||||
|
public:
|
||||||
|
Constructor() = default;
|
||||||
|
Constructor(int) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void testConstructor() {
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user