forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.9'
Conflicts: qbs/modules/qtc/qtc.qbs qtcreator.pri src/plugins/debugger/debuggerkitinformation.cpp src/plugins/languageclient/languageclientmanager.cpp src/plugins/plugins.pro src/plugins/projectexplorer/kit.cpp src/plugins/projectexplorer/kitmanager.cpp Change-Id: I66fb941202991f35f7d7761430b21e42dfc678a8
This commit is contained in:
@@ -68,13 +68,12 @@ void ClangCodeModelPlugin::generateCompilationDB() {
|
||||
using namespace CppTools;
|
||||
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||
if (!project)
|
||||
if (!project || !project->activeTarget())
|
||||
return;
|
||||
|
||||
m_generatorWatcher.setFuture(QtConcurrent::run(
|
||||
&Utils::generateCompilationDB,
|
||||
project->projectDirectory(),
|
||||
CppModelManager::instance()->projectInfo(project)));
|
||||
m_generatorWatcher.setFuture(
|
||||
QtConcurrent::run(&Utils::generateCompilationDB,
|
||||
CppModelManager::instance()->projectInfo(project)));
|
||||
}
|
||||
|
||||
static bool isDBGenerationEnabled(ProjectExplorer::Project *project)
|
||||
|
||||
@@ -214,6 +214,9 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions(const CodeComple
|
||||
setAsyncProposalAvailable(createFunctionHintProposal(completions));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_fallbackToNormalCompletion)
|
||||
return;
|
||||
// else: Proceed with a normal completion in case:
|
||||
// 1) it was not a function call, but e.g. a function declaration like "void f("
|
||||
// 2) '{' meant not a constructor call.
|
||||
@@ -286,6 +289,14 @@ static QByteArray modifyInput(QTextDocument *doc, int endOfExpression) {
|
||||
return modifiedInput;
|
||||
}
|
||||
|
||||
static QChar lastPrecedingNonWhitespaceChar(const ClangCompletionAssistInterface *interface)
|
||||
{
|
||||
int pos = interface->position();
|
||||
while (pos >= 0 && interface->characterAt(pos).isSpace())
|
||||
--pos;
|
||||
return pos >= 0 ? interface->characterAt(pos) : QChar::Null;
|
||||
}
|
||||
|
||||
IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
|
||||
{
|
||||
ClangCompletionContextAnalyzer analyzer(m_interface.data(), m_interface->languageFeatures());
|
||||
@@ -323,6 +334,8 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
|
||||
}
|
||||
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: {
|
||||
m_sentRequestType = FunctionHintCompletion;
|
||||
if (lastPrecedingNonWhitespaceChar(m_interface.data()) == ',')
|
||||
m_fallbackToNormalCompletion = false;
|
||||
m_requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray(),
|
||||
analyzer.functionNameStart());
|
||||
break;
|
||||
|
||||
@@ -97,6 +97,7 @@ private:
|
||||
CompletionRequestType m_sentRequestType = NormalCompletion;
|
||||
bool m_requestSent = false;
|
||||
bool m_addSnippets = false; // For type == Type::NormalCompletion
|
||||
bool m_fallbackToNormalCompletion = true;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -110,6 +110,8 @@ int ClangCompletionContextAnalyzer::startOfFunctionCall(int endOfOperator) const
|
||||
functionNameSelector.setPosition(functionNameStart);
|
||||
functionNameSelector.setPosition(index, QTextCursor::KeepAnchor);
|
||||
const QString functionName = functionNameSelector.selectedText().trimmed();
|
||||
if (functionName.isEmpty() && m_completionOperator == T_LBRACE)
|
||||
return endOfOperator;
|
||||
|
||||
return functionName.isEmpty() ? -1 : functionNameStart;
|
||||
}
|
||||
@@ -139,7 +141,10 @@ void ClangCompletionContextAnalyzer::handleCommaInFunctionCall()
|
||||
const int start = expressionUnderCursor.startOfFunctionCall(textCursor);
|
||||
m_positionEndOfExpression = start;
|
||||
m_positionForProposal = start + 1; // After '(' of function call
|
||||
m_completionOperator = T_LPAREN;
|
||||
if (m_interface->characterAt(start) == '(')
|
||||
m_completionOperator = T_LPAREN;
|
||||
else
|
||||
m_completionOperator = T_LBRACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,13 @@
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <cpptools/baseeditordocumentparser.h>
|
||||
#include <cpptools/compileroptionsbuilder.h>
|
||||
#include <cpptools/cppcodemodelsettings.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
#include <cpptools/editordocumenthandle.h>
|
||||
#include <cpptools/projectpart.h>
|
||||
#include <cpptools/cppcodemodelsettings.h>
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
#include <projectexplorer/buildconfiguration.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
@@ -300,12 +301,24 @@ QString diagnosticCategoryPrefixRemoved(const QString &text)
|
||||
return text;
|
||||
}
|
||||
|
||||
static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart)
|
||||
static ::Utils::FileName compilerPath(const CppTools::ProjectPart &projectPart)
|
||||
{
|
||||
ProjectExplorer::Target *target = projectPart.project->activeTarget();
|
||||
if (!target)
|
||||
return ::Utils::FileName();
|
||||
|
||||
ProjectExplorer::ToolChain *toolchain = ProjectExplorer::ToolChainKitAspect::toolChain(
|
||||
target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
||||
|
||||
return toolchain->compilerCommand();
|
||||
}
|
||||
|
||||
static ::Utils::FileName buildDirectory(const ProjectExplorer::Project &project)
|
||||
{
|
||||
ProjectExplorer::Target *target = project.activeTarget();
|
||||
if (!target)
|
||||
return ::Utils::FileName();
|
||||
|
||||
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration();
|
||||
if (!buildConfig)
|
||||
return ::Utils::FileName();
|
||||
@@ -313,42 +326,84 @@ static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart
|
||||
return buildConfig->buildDirectory();
|
||||
}
|
||||
|
||||
static QJsonObject createFileObject(CompilerOptionsBuilder &optionsBuilder,
|
||||
const ProjectFile &projFile,
|
||||
const ::Utils::FileName &buildDir)
|
||||
static QStringList projectPartArguments(const ProjectPart &projectPart)
|
||||
{
|
||||
const ProjectFile::Kind kind = ProjectFile::classify(projFile.path);
|
||||
optionsBuilder.updateFileLanguage(kind);
|
||||
QStringList args;
|
||||
args << compilerPath(projectPart).toString();
|
||||
args << "-c";
|
||||
if (projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
||||
args << "--target=" + projectPart.toolChainTargetTriple;
|
||||
args << (projectPart.toolChainWordWidth == ProjectPart::WordWidth64Bit
|
||||
? QLatin1String("-m64")
|
||||
: QLatin1String("-m32"));
|
||||
}
|
||||
args << projectPart.compilerFlags;
|
||||
for (const ProjectExplorer::HeaderPath &headerPath : projectPart.headerPaths) {
|
||||
if (headerPath.type == ProjectExplorer::HeaderPathType::User) {
|
||||
args << "-I" + headerPath.path;
|
||||
} else if (headerPath.type == ProjectExplorer::HeaderPathType::System) {
|
||||
args << (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
||||
? "-I"
|
||||
: "-isystem")
|
||||
+ headerPath.path;
|
||||
}
|
||||
}
|
||||
for (const ProjectExplorer::Macro ¯o : projectPart.projectMacros) {
|
||||
args.append(QString::fromUtf8(
|
||||
macro.toKeyValue(macro.type == ProjectExplorer::MacroType::Define ? "-D" : "-U")));
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
static QJsonObject createFileObject(const ::Utils::FileName &buildDir,
|
||||
const QStringList &arguments,
|
||||
const ProjectPart &projectPart,
|
||||
const ProjectFile &projFile)
|
||||
{
|
||||
QJsonObject fileObject;
|
||||
fileObject["file"] = projFile.path;
|
||||
QJsonArray args = QJsonArray::fromStringList(optionsBuilder.options());
|
||||
args.prepend(kind == ProjectFile::CXXSource ? "clang++" : "clang");
|
||||
QJsonArray args = QJsonArray::fromStringList(arguments);
|
||||
|
||||
const ProjectFile::Kind kind = ProjectFile::classify(projFile.path);
|
||||
if (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
||||
|| projectPart.toolchainType == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
|
||||
if (ProjectFile::isC(kind))
|
||||
args.append("/TC");
|
||||
else if (ProjectFile::isCxx(kind))
|
||||
args.append("/TP");
|
||||
} else {
|
||||
QStringList langOption
|
||||
= createLanguageOptionGcc(kind,
|
||||
projectPart.languageExtensions
|
||||
& ::Utils::LanguageExtension::ObjectiveC);
|
||||
for (const QString &langOptionPart : langOption)
|
||||
args.append(langOptionPart);
|
||||
}
|
||||
args.append(QDir::toNativeSeparators(projFile.path));
|
||||
fileObject["arguments"] = args;
|
||||
fileObject["directory"] = buildDir.toString();
|
||||
return fileObject;
|
||||
}
|
||||
|
||||
void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo)
|
||||
void generateCompilationDB(CppTools::ProjectInfo projectInfo)
|
||||
{
|
||||
QFile compileCommandsFile(projectDir.toString() + "/compile_commands.json");
|
||||
const ::Utils::FileName buildDir = buildDirectory(*projectInfo.project());
|
||||
QTC_ASSERT(!buildDir.isEmpty(), return;);
|
||||
|
||||
QDir dir(buildDir.toString());
|
||||
if (!dir.exists())
|
||||
dir.mkpath(dir.path());
|
||||
QFile compileCommandsFile(buildDir.toString() + "/compile_commands.json");
|
||||
const bool fileOpened = compileCommandsFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
if (!fileOpened)
|
||||
return;
|
||||
compileCommandsFile.write("[");
|
||||
|
||||
for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
|
||||
const ::Utils::FileName buildDir = buildDirectory(*projectPart);
|
||||
|
||||
CompilerOptionsBuilder optionsBuilder(*projectPart,
|
||||
UseSystemHeader::No,
|
||||
UseTweakedHeaderPaths::No);
|
||||
optionsBuilder.build(CppTools::ProjectFile::Unclassified,
|
||||
CppTools::UsePrecompiledHeaders::No);
|
||||
|
||||
const QStringList args = projectPartArguments(*projectPart);
|
||||
for (const ProjectFile &projFile : projectPart->files) {
|
||||
const QJsonObject json = createFileObject(optionsBuilder, projFile, buildDir);
|
||||
const QJsonObject json = createFileObject(buildDir, args, *projectPart, projFile);
|
||||
if (compileCommandsFile.size() > 1)
|
||||
compileCommandsFile.write(",");
|
||||
compileCommandsFile.write('\n' + QJsonDocument(json).toJson().trimmed());
|
||||
|
||||
@@ -70,7 +70,7 @@ QString diagnosticCategoryPrefixRemoved(const QString &text);
|
||||
|
||||
::Utils::CodeModelIcon::Type iconTypeForToken(const ClangBackEnd::TokenInfoContainer &token);
|
||||
|
||||
void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo);
|
||||
void generateCompilationDB(CppTools::ProjectInfo projectInfo);
|
||||
|
||||
class DiagnosticTextInfo
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user