forked from qt-creator/qt-creator
Merge remote-tracking branch 'gerrit/3.2'
Change-Id: I2567b8f19e502777f6566ce573a6970fb62a7521
This commit is contained in:
@@ -51,7 +51,7 @@ static void parse(QFutureInterface<void> &future,
|
||||
bool processingHeaders = false;
|
||||
|
||||
CppModelManager *cmm = CppModelManager::instance();
|
||||
const QStringList fallbackIncludePaths = cmm->includePaths();
|
||||
const ProjectPart::HeaderPaths fallbackHeaderPaths = cmm->headerPaths();
|
||||
for (int i = 0; i < files.size(); ++i) {
|
||||
if (future.isPaused())
|
||||
future.waitForResume();
|
||||
@@ -71,10 +71,10 @@ static void parse(QFutureInterface<void> &future,
|
||||
}
|
||||
|
||||
QList<ProjectPart::Ptr> parts = cmm->projectPart(fileName);
|
||||
QStringList includePaths = parts.isEmpty()
|
||||
? fallbackIncludePaths
|
||||
: parts.first()->includePaths;
|
||||
sourceProcessor->setIncludePaths(includePaths);
|
||||
ProjectPart::HeaderPaths headerPaths = parts.isEmpty()
|
||||
? fallbackHeaderPaths
|
||||
: parts.first()->headerPaths;
|
||||
sourceProcessor->setHeaderPaths(headerPaths);
|
||||
sourceProcessor->run(fileName);
|
||||
|
||||
future.setProgressValue(files.size() - sourceProcessor->todo().size());
|
||||
@@ -190,8 +190,7 @@ QFuture<void> BuiltinIndexingSupport::refreshSourceFiles(const QStringList &sour
|
||||
CppSourceProcessor *preproc = CppModelManager::createSourceProcessor();
|
||||
preproc->setDumpFileNameWhileParsing(m_dumpFileNameWhileParsing);
|
||||
preproc->setRevision(++m_revision);
|
||||
preproc->setIncludePaths(mgr->includePaths());
|
||||
preproc->setFrameworkPaths(mgr->frameworkPaths());
|
||||
preproc->setHeaderPaths(mgr->headerPaths());
|
||||
preproc->setWorkingCopy(workingCopy);
|
||||
|
||||
QFuture<void> result = QtConcurrent::run(&parse, preproc, sourceFiles);
|
||||
|
||||
@@ -413,6 +413,18 @@ QString Utils::pathListToString(const QStringList &pathList)
|
||||
return result.join(QLatin1String("\n"));
|
||||
}
|
||||
|
||||
QString Utils::pathListToString(const ProjectPart::HeaderPaths &pathList)
|
||||
{
|
||||
QStringList result;
|
||||
foreach (const ProjectPart::HeaderPath &path, pathList) {
|
||||
result << QString(QLatin1String("%1 (%2 path)")).arg(
|
||||
QDir::toNativeSeparators(path.path),
|
||||
path.isFrameworkPath() ? QLatin1String("framework") : QLatin1String("include")
|
||||
);
|
||||
}
|
||||
return result.join(QLatin1String("\n"));
|
||||
}
|
||||
|
||||
QList<CPlusPlus::Document::Ptr> Utils::snapshotToList(const CPlusPlus::Snapshot &snapshot)
|
||||
{
|
||||
QList<CPlusPlus::Document::Ptr> documents;
|
||||
@@ -511,16 +523,14 @@ void Dumper::dumpProjectInfos( const QList<CppModelManagerInterface::ProjectInfo
|
||||
m_out << i4 << defineLine << "\n";
|
||||
}
|
||||
|
||||
if (!part->includePaths.isEmpty()) {
|
||||
m_out << i3 << "Include Paths:{{{4\n";
|
||||
foreach (const QString &includePath, part->includePaths)
|
||||
m_out << i4 << includePath << "\n";
|
||||
}
|
||||
|
||||
if (!part->frameworkPaths.isEmpty()) {
|
||||
m_out << i3 << "Framework Paths:{{{4\n";
|
||||
foreach (const QString &frameworkPath, part->frameworkPaths)
|
||||
m_out << i4 << frameworkPath << "\n";
|
||||
if (!part->headerPaths.isEmpty()) {
|
||||
m_out << i3 << "Header Paths:{{{4\n";
|
||||
foreach (const ProjectPart::HeaderPath &headerPath, part->headerPaths)
|
||||
m_out << i4 << headerPath.path
|
||||
<< (headerPath.type == ProjectPart::HeaderPath::IncludePath
|
||||
? "(include path)"
|
||||
: "(framework path)")
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if (!part->precompiledHeaders.isEmpty()) {
|
||||
@@ -582,18 +592,18 @@ void Dumper::dumpWorkingCopy(const CppModelManagerInterface::WorkingCopy &workin
|
||||
}
|
||||
}
|
||||
|
||||
void Dumper::dumpMergedEntities(const QStringList &mergedIncludePaths,
|
||||
const QStringList &mergedFrameworkPaths,
|
||||
void Dumper::dumpMergedEntities(const ProjectPart::HeaderPaths &mergedHeaderPaths,
|
||||
const QByteArray &mergedMacros)
|
||||
{
|
||||
m_out << "Merged Entities{{{1\n";
|
||||
const QByteArray i2 = indent(2);
|
||||
const QByteArray i3 = indent(3);
|
||||
|
||||
m_out << i2 << "Merged Include Paths{{{2\n";
|
||||
dumpStringList(mergedIncludePaths, i3);
|
||||
m_out << i2 << "Merged Framework Paths{{{2\n";
|
||||
dumpStringList(mergedFrameworkPaths, i3);
|
||||
m_out << i2 << "Merged Header Paths{{{2\n";
|
||||
foreach (const ProjectPart::HeaderPath &hp, mergedHeaderPaths)
|
||||
m_out << i3 << hp.path
|
||||
<< (hp.isFrameworkPath() ? " (framework path)" : " (include path)")
|
||||
<< "\n";
|
||||
m_out << i2 << "Merged Defines{{{2\n";
|
||||
m_out << mergedMacros;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ struct CPPTOOLS_EXPORT Utils
|
||||
static QString partsForFile(const QString &fileName);
|
||||
static QString unresolvedFileNameWithDelimiters(const CPlusPlus::Document::Include &include);
|
||||
static QString pathListToString(const QStringList &pathList);
|
||||
static QString pathListToString(const ProjectPart::HeaderPaths &pathList);
|
||||
static QList<CPlusPlus::Document::Ptr> snapshotToList(const CPlusPlus::Snapshot &snapshot);
|
||||
};
|
||||
|
||||
@@ -73,8 +74,7 @@ public:
|
||||
const QString &title,
|
||||
bool isGlobalSnapshot = false);
|
||||
void dumpWorkingCopy(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy);
|
||||
void dumpMergedEntities(const QStringList &mergedIncludePaths,
|
||||
const QStringList &mergedFrameworkPaths,
|
||||
void dumpMergedEntities(const ProjectPart::HeaderPaths &mergedHeaderPaths,
|
||||
const QByteArray &mergedMacros);
|
||||
|
||||
private:
|
||||
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
= new CppCompletionAssistInterface(m_editorWidget->document(), m_position,
|
||||
m_editorWidget->baseTextDocument()->filePath(),
|
||||
ExplicitlyInvoked, m_snapshot,
|
||||
QStringList(), QStringList());
|
||||
ProjectPart::HeaderPaths());
|
||||
CppCompletionAssistProcessor processor;
|
||||
IAssistProposal *proposal = processor.perform(ai);
|
||||
if (!proposal)
|
||||
@@ -2263,6 +2263,24 @@ void CppToolsPlugin::test_completion_data()
|
||||
) << _("n2.n1.t.") << (QStringList()
|
||||
<< QLatin1String("foo")
|
||||
<< QLatin1String("Foo"));
|
||||
|
||||
QTest::newRow("lambda_parameter") << _(
|
||||
"auto func = [](int arg1) { return @; };\n"
|
||||
) << _("ar") << (QStringList()
|
||||
<< QLatin1String("arg1"));
|
||||
|
||||
QTest::newRow("default_arguments_for_class_templates_and_base_class_QTCREATORBUG-12605") << _(
|
||||
"struct Foo { int foo; };\n"
|
||||
"template <typename T = Foo>\n"
|
||||
"struct Derived : T {};\n"
|
||||
"void fun() {\n"
|
||||
" Derived<> derived;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("derived.") << (QStringList()
|
||||
<< QLatin1String("Derived")
|
||||
<< QLatin1String("foo")
|
||||
<< QLatin1String("Foo"));
|
||||
}
|
||||
|
||||
void CppToolsPlugin::test_completion_member_access_operator()
|
||||
|
||||
@@ -1139,30 +1139,23 @@ bool CppCompletionAssistProcessor::completeInclude(const QTextCursor &cursor)
|
||||
}
|
||||
|
||||
// Make completion for all relevant includes
|
||||
QStringList includePaths = m_interface->includePaths();
|
||||
const QString ¤tFilePath = QFileInfo(m_interface->fileName()).path();
|
||||
if (!includePaths.contains(currentFilePath))
|
||||
includePaths.append(currentFilePath);
|
||||
ProjectPart::HeaderPaths headerPaths = m_interface->headerPaths();
|
||||
const ProjectPart::HeaderPath currentFilePath(QFileInfo(m_interface->fileName()).path(),
|
||||
ProjectPart::HeaderPath::IncludePath);
|
||||
if (!headerPaths.contains(currentFilePath))
|
||||
headerPaths.append(currentFilePath);
|
||||
|
||||
const Core::MimeType mimeType =
|
||||
Core::MimeDatabase::findByType(QLatin1String("text/x-c++hdr"));
|
||||
const QStringList suffixes = mimeType.suffixes();
|
||||
|
||||
foreach (const QString &includePath, includePaths) {
|
||||
QString realPath = includePath;
|
||||
foreach (const ProjectPart::HeaderPath &headerPath, headerPaths) {
|
||||
QString realPath = headerPath.path;
|
||||
if (!directoryPrefix.isEmpty()) {
|
||||
realPath += QLatin1Char('/');
|
||||
realPath += directoryPrefix;
|
||||
}
|
||||
completeInclude(realPath, suffixes);
|
||||
}
|
||||
|
||||
foreach (const QString &frameworkPath, m_interface->frameworkPaths()) {
|
||||
QString realPath = frameworkPath;
|
||||
if (!directoryPrefix.isEmpty()) {
|
||||
realPath += QLatin1Char('/');
|
||||
realPath += directoryPrefix;
|
||||
realPath += QLatin1String(".framework/Headers");
|
||||
if (headerPath.isFrameworkPath())
|
||||
realPath += QLatin1String(".framework/Headers");
|
||||
}
|
||||
completeInclude(realPath, suffixes);
|
||||
}
|
||||
@@ -1969,8 +1962,7 @@ void CppCompletionAssistInterface::getCppSpecifics() const
|
||||
if (QSharedPointer<SnapshotUpdater> updater = supp->snapshotUpdater()) {
|
||||
updater->update(m_workingCopy);
|
||||
m_snapshot = updater->snapshot();
|
||||
m_includePaths = updater->includePaths();
|
||||
m_frameworkPaths = updater->frameworkPaths();
|
||||
m_headerPaths = updater->headerPaths();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,22 +191,20 @@ public:
|
||||
const QString &fileName,
|
||||
TextEditor::AssistReason reason,
|
||||
const CPlusPlus::Snapshot &snapshot,
|
||||
const QStringList &includePaths,
|
||||
const QStringList &frameworkPaths)
|
||||
const ProjectPart::HeaderPaths &headerPaths)
|
||||
: TextEditor::DefaultAssistInterface(textDocument, position, fileName, reason)
|
||||
, m_editor(0)
|
||||
, m_isObjCEnabled(false)
|
||||
, m_gotCppSpecifics(true)
|
||||
, m_snapshot(snapshot)
|
||||
, m_includePaths(includePaths)
|
||||
, m_frameworkPaths(frameworkPaths)
|
||||
, m_headerPaths(headerPaths)
|
||||
{}
|
||||
|
||||
bool isObjCEnabled() const { return m_isObjCEnabled; }
|
||||
|
||||
const CPlusPlus::Snapshot &snapshot() const { getCppSpecifics(); return m_snapshot; }
|
||||
const QStringList &includePaths() const { getCppSpecifics(); return m_includePaths; }
|
||||
const QStringList &frameworkPaths() const { getCppSpecifics(); return m_frameworkPaths; }
|
||||
const ProjectPart::HeaderPaths &headerPaths() const
|
||||
{ getCppSpecifics(); return m_headerPaths; }
|
||||
|
||||
private:
|
||||
void getCppSpecifics() const;
|
||||
@@ -216,8 +214,7 @@ private:
|
||||
mutable bool m_gotCppSpecifics;
|
||||
CppModelManagerInterface::WorkingCopy m_workingCopy;
|
||||
mutable CPlusPlus::Snapshot m_snapshot;
|
||||
mutable QStringList m_includePaths;
|
||||
mutable QStringList m_frameworkPaths;
|
||||
mutable ProjectPart::HeaderPaths m_headerPaths;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
|
||||
@@ -39,12 +39,9 @@ namespace {
|
||||
|
||||
class FindLocalSymbols: protected ASTVisitor
|
||||
{
|
||||
Scope *_functionScope;
|
||||
Document::Ptr _doc;
|
||||
|
||||
public:
|
||||
FindLocalSymbols(Document::Ptr doc)
|
||||
: ASTVisitor(doc->translationUnit()), _doc(doc)
|
||||
: ASTVisitor(doc->translationUnit())
|
||||
{ }
|
||||
|
||||
// local and external uses.
|
||||
@@ -59,12 +56,10 @@ public:
|
||||
|
||||
if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) {
|
||||
if (def->symbol) {
|
||||
_functionScope = def->symbol;
|
||||
accept(ast);
|
||||
}
|
||||
} else if (ObjCMethodDeclarationAST *decl = ast->asObjCMethodDeclaration()) {
|
||||
if (decl->method_prototype->symbol) {
|
||||
_functionScope = decl->method_prototype->symbol;
|
||||
accept(ast);
|
||||
}
|
||||
}
|
||||
@@ -180,6 +175,19 @@ protected:
|
||||
_scopeStack.removeLast();
|
||||
}
|
||||
|
||||
virtual bool visit(LambdaExpressionAST *ast)
|
||||
{
|
||||
if (ast->lambda_declarator && ast->lambda_declarator->symbol)
|
||||
enterScope(ast->lambda_declarator->symbol);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void endVisit(LambdaExpressionAST *ast)
|
||||
{
|
||||
if (ast->lambda_declarator && ast->lambda_declarator->symbol)
|
||||
_scopeStack.removeLast();
|
||||
}
|
||||
|
||||
virtual bool visit(CompoundStatementAST *ast)
|
||||
{
|
||||
if (ast->symbol)
|
||||
|
||||
200
src/plugins/cpptools/cpplocalsymbols_test.cpp
Normal file
200
src/plugins/cpptools/cpplocalsymbols_test.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "cpptoolsplugin.h"
|
||||
|
||||
#include "cpplocalsymbols.h"
|
||||
#include "cppsemanticinfo.h"
|
||||
|
||||
#include <cplusplus/Overview.h>
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
namespace {
|
||||
|
||||
class FindFirstFunctionDefinition: protected CPlusPlus::ASTVisitor
|
||||
{
|
||||
public:
|
||||
FindFirstFunctionDefinition(CPlusPlus::TranslationUnit *translationUnit)
|
||||
: ASTVisitor(translationUnit)
|
||||
, m_definition(0)
|
||||
{}
|
||||
|
||||
CPlusPlus::FunctionDefinitionAST *operator()()
|
||||
{
|
||||
accept(translationUnit()->ast());
|
||||
return m_definition;
|
||||
}
|
||||
|
||||
private:
|
||||
bool preVisit(CPlusPlus::AST *ast)
|
||||
{
|
||||
if (CPlusPlus::FunctionDefinitionAST *f = ast->asFunctionDefinition()) {
|
||||
m_definition = f;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
CPlusPlus::FunctionDefinitionAST *m_definition;
|
||||
};
|
||||
|
||||
struct Result
|
||||
{
|
||||
Result() : line(0), column(0), length(0) {}
|
||||
Result(const QByteArray &name, unsigned line, unsigned column, unsigned length)
|
||||
: name(name), line(line), column(column), length(length)
|
||||
{}
|
||||
|
||||
QByteArray name;
|
||||
unsigned line;
|
||||
unsigned column;
|
||||
unsigned length;
|
||||
|
||||
bool operator==(const Result &other) const
|
||||
{
|
||||
return name == other.name
|
||||
&& line == other.line
|
||||
&& column == other.column
|
||||
&& length == other.length;
|
||||
}
|
||||
|
||||
static Result fromHighlightingResult(const CPlusPlus::Symbol *symbol,
|
||||
TextEditor::HighlightingResult result)
|
||||
{
|
||||
const QByteArray name = CPlusPlus::Overview().prettyName(symbol->name()).toLatin1();
|
||||
return Result(name, result.line, result.column, result.length);
|
||||
}
|
||||
|
||||
static QList<Result> fromLocalUses(CppTools::SemanticInfo::LocalUseMap localUses)
|
||||
{
|
||||
QList<Result> result;
|
||||
|
||||
CppTools::SemanticInfo::LocalUseIterator it(localUses);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
const CPlusPlus::Symbol *symbol = it.key();
|
||||
const QList<CppTools::SemanticInfo::Use> &uses = it.value();
|
||||
foreach (const CppTools::SemanticInfo::Use &use, uses)
|
||||
result << fromHighlightingResult(symbol, use);
|
||||
}
|
||||
|
||||
Utils::sort(result, [](const Result &r1, const Result &r2) -> bool {
|
||||
if (r1.line == r2.line)
|
||||
return r1.column < r2.column;
|
||||
return r1.line < r2.line;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
Q_DECLARE_METATYPE(Result)
|
||||
Q_DECLARE_METATYPE(QList<Result>)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace QTest {
|
||||
template<>
|
||||
char *toString(const Result &result)
|
||||
{
|
||||
QByteArray ba = "Result(";
|
||||
ba += "_(\"" + result.name + "\"), ";
|
||||
ba += QByteArray::number(result.line) + ", ";
|
||||
ba += QByteArray::number(result.column) + ", ";
|
||||
ba += QByteArray::number(result.length) + ")";
|
||||
return qstrdup(ba.data());
|
||||
}
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace CppTools {
|
||||
namespace Internal {
|
||||
|
||||
void CppToolsPlugin::test_cpplocalsymbols_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("source");
|
||||
QTest::addColumn<QList<Result>>("expectedUses");
|
||||
|
||||
typedef QByteArray _;
|
||||
|
||||
QTest::newRow("basic")
|
||||
<< _("int f(int arg)\n"
|
||||
"{\n"
|
||||
" int local;\n"
|
||||
" g(&local);\n"
|
||||
" return local + arg;\n"
|
||||
"}\n")
|
||||
<< (QList<Result>()
|
||||
<< Result(_("arg"), 0, 10, 3)
|
||||
<< Result(_("local"), 2, 9, 5)
|
||||
<< Result(_("local"), 3, 8, 5)
|
||||
<< Result(_("local"), 4, 12, 5)
|
||||
<< Result(_("arg"), 4, 20, 3));
|
||||
|
||||
QTest::newRow("lambda")
|
||||
<< _("void f()\n"
|
||||
"{\n"
|
||||
" auto func = [](int arg) { return arg; };\n"
|
||||
" func(1);\n"
|
||||
"}\n")
|
||||
<< (QList<Result>()
|
||||
<< Result(_("func"), 2, 10, 4)
|
||||
<< Result(_("arg"), 2, 24, 3)
|
||||
<< Result(_("arg"), 2, 38, 3)
|
||||
<< Result(_("func"), 3, 5, 4));
|
||||
}
|
||||
|
||||
void CppToolsPlugin::test_cpplocalsymbols()
|
||||
{
|
||||
QFETCH(QByteArray, source);
|
||||
QFETCH(QList<Result>, expectedUses);
|
||||
|
||||
CPlusPlus::Document::Ptr document = CPlusPlus::Document::create(QLatin1String("test.cpp"));
|
||||
document->setUtf8Source(source);
|
||||
document->check();
|
||||
QVERIFY(document->diagnosticMessages().isEmpty());
|
||||
QVERIFY(document->translationUnit());
|
||||
QVERIFY(document->translationUnit()->ast());
|
||||
QVERIFY(document->globalNamespace());
|
||||
FindFirstFunctionDefinition find(document->translationUnit());
|
||||
CPlusPlus::DeclarationAST *functionDefinition = find();
|
||||
|
||||
LocalSymbols localSymbols(document, functionDefinition);
|
||||
|
||||
const QList<Result> actualUses = Result::fromLocalUses(localSymbols.uses);
|
||||
// foreach (const Result &result, actualUses)
|
||||
// qDebug() << QTest::toString(result);
|
||||
QCOMPARE(actualUses, expectedUses);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CppTools
|
||||
@@ -298,8 +298,7 @@ void CppModelManager::ensureUpdated()
|
||||
return;
|
||||
|
||||
m_projectFiles = internalProjectFiles();
|
||||
m_includePaths = internalIncludePaths();
|
||||
m_frameworkPaths = internalFrameworkPaths();
|
||||
m_headerPaths = internalHeaderPaths();
|
||||
m_definedMacros = internalDefinedMacros();
|
||||
m_dirty = false;
|
||||
}
|
||||
@@ -320,34 +319,23 @@ QStringList CppModelManager::internalProjectFiles() const
|
||||
return files;
|
||||
}
|
||||
|
||||
QStringList CppModelManager::internalIncludePaths() const
|
||||
ProjectPart::HeaderPaths CppModelManager::internalHeaderPaths() const
|
||||
{
|
||||
QStringList includePaths;
|
||||
ProjectPart::HeaderPaths headerPaths;
|
||||
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projectToProjectsInfo);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
const ProjectInfo pinfo = it.value();
|
||||
foreach (const ProjectPart::Ptr &part, pinfo.projectParts())
|
||||
foreach (const QString &path, part->includePaths)
|
||||
includePaths.append(CppSourceProcessor::cleanPath(path));
|
||||
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
|
||||
foreach (const ProjectPart::HeaderPath &path, part->headerPaths) {
|
||||
const ProjectPart::HeaderPath hp(CppSourceProcessor::cleanPath(path.path),
|
||||
path.type);
|
||||
if (!headerPaths.contains(hp))
|
||||
headerPaths += hp;
|
||||
}
|
||||
}
|
||||
}
|
||||
includePaths.removeDuplicates();
|
||||
return includePaths;
|
||||
}
|
||||
|
||||
QStringList CppModelManager::internalFrameworkPaths() const
|
||||
{
|
||||
QStringList frameworkPaths;
|
||||
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projectToProjectsInfo);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
const ProjectInfo pinfo = it.value();
|
||||
foreach (const ProjectPart::Ptr &part, pinfo.projectParts())
|
||||
foreach (const QString &path, part->frameworkPaths)
|
||||
frameworkPaths.append(CppSourceProcessor::cleanPath(path));
|
||||
}
|
||||
frameworkPaths.removeDuplicates();
|
||||
return frameworkPaths;
|
||||
return headerPaths;
|
||||
}
|
||||
|
||||
static void addUnique(const QList<QByteArray> &defs, QByteArray *macros, QSet<QByteArray> *alreadyIn)
|
||||
@@ -396,7 +384,7 @@ void CppModelManager::dumpModelManagerConfiguration(const QString &logFileId)
|
||||
dumper.dumpSnapshot(globalSnapshot, globalSnapshotTitle, /*isGlobalSnapshot=*/ true);
|
||||
dumper.dumpWorkingCopy(workingCopy());
|
||||
ensureUpdated();
|
||||
dumper.dumpMergedEntities(m_includePaths, m_frameworkPaths, m_definedMacros);
|
||||
dumper.dumpMergedEntities(m_headerPaths, m_definedMacros);
|
||||
}
|
||||
|
||||
void CppModelManager::addExtraEditorSupport(AbstractEditorSupport *editorSupport)
|
||||
@@ -595,8 +583,7 @@ public:
|
||||
bool configurationChanged() const
|
||||
{
|
||||
return definesChanged()
|
||||
|| m_new.includePaths() != m_old.includePaths()
|
||||
|| m_new.frameworkPaths() != m_old.frameworkPaths();
|
||||
|| m_new.headerPaths() != m_old.headerPaths();
|
||||
}
|
||||
|
||||
bool nothingChanged() const
|
||||
@@ -761,8 +748,7 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart() const
|
||||
ProjectPart::Ptr part(new ProjectPart);
|
||||
|
||||
part->projectDefines = m_definedMacros;
|
||||
part->includePaths = m_includePaths;
|
||||
part->frameworkPaths = m_frameworkPaths;
|
||||
part->headerPaths = m_headerPaths;
|
||||
part->cVersion = ProjectPart::C11;
|
||||
part->cxxVersion = ProjectPart::CXX11;
|
||||
part->cxxExtensions = ProjectPart::AllExtensions;
|
||||
|
||||
@@ -128,22 +128,16 @@ public:
|
||||
return m_projectFiles;
|
||||
}
|
||||
|
||||
QStringList includePaths()
|
||||
ProjectPart::HeaderPaths headerPaths()
|
||||
{
|
||||
ensureUpdated();
|
||||
return m_includePaths;
|
||||
return m_headerPaths;
|
||||
}
|
||||
|
||||
// Use this *only* for auto tests
|
||||
void setIncludePaths(const QStringList &includePaths)
|
||||
void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths)
|
||||
{
|
||||
m_includePaths = includePaths;
|
||||
}
|
||||
|
||||
QStringList frameworkPaths()
|
||||
{
|
||||
ensureUpdated();
|
||||
return m_frameworkPaths;
|
||||
m_headerPaths = headerPaths;
|
||||
}
|
||||
|
||||
QByteArray definedMacros()
|
||||
@@ -187,8 +181,7 @@ private:
|
||||
|
||||
void ensureUpdated();
|
||||
QStringList internalProjectFiles() const;
|
||||
QStringList internalIncludePaths() const;
|
||||
QStringList internalFrameworkPaths() const;
|
||||
ProjectPart::HeaderPaths internalHeaderPaths() const;
|
||||
QByteArray internalDefinedMacros() const;
|
||||
|
||||
void dumpModelManagerConfiguration(const QString &logFileId);
|
||||
@@ -210,8 +203,7 @@ private:
|
||||
// The members below are cached/(re)calculated from the projects and/or their project parts
|
||||
bool m_dirty;
|
||||
QStringList m_projectFiles;
|
||||
QStringList m_includePaths;
|
||||
QStringList m_frameworkPaths;
|
||||
ProjectPart::HeaderPaths m_headerPaths;
|
||||
QByteArray m_definedMacros;
|
||||
|
||||
// Editor integration
|
||||
|
||||
@@ -220,23 +220,24 @@ void CppToolsPlugin::test_modelmanager_paths_are_clean()
|
||||
ProjectInfo pi = mm->projectInfo(project);
|
||||
QCOMPARE(pi.project().data(), project);
|
||||
|
||||
typedef ProjectPart::HeaderPath HeaderPath;
|
||||
|
||||
ProjectPart::Ptr part(new ProjectPart);
|
||||
part->cxxVersion = ProjectPart::CXX98;
|
||||
part->qtVersion = ProjectPart::Qt5;
|
||||
part->projectDefines = QByteArray("#define OH_BEHAVE -1\n");
|
||||
part->includePaths = QStringList() << testDataDir.includeDir(false);
|
||||
part->frameworkPaths = QStringList() << testDataDir.frameworksDir(false);
|
||||
part->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath)
|
||||
<< HeaderPath(testDataDir.frameworksDir(false), HeaderPath::FrameworkPath);
|
||||
pi.appendProjectPart(part);
|
||||
|
||||
mm->updateProjectInfo(pi);
|
||||
|
||||
QStringList includePaths = mm->includePaths();
|
||||
QCOMPARE(includePaths.size(), 1);
|
||||
QVERIFY(includePaths.contains(testDataDir.includeDir()));
|
||||
|
||||
QStringList frameworkPaths = mm->frameworkPaths();
|
||||
QCOMPARE(frameworkPaths.size(), 1);
|
||||
QVERIFY(frameworkPaths.contains(testDataDir.frameworksDir()));
|
||||
QList<HeaderPath> headerPaths = mm->headerPaths();
|
||||
QCOMPARE(headerPaths.size(), 2);
|
||||
QVERIFY(headerPaths.contains(HeaderPath(testDataDir.includeDir(), HeaderPath::IncludePath)));
|
||||
QVERIFY(headerPaths.contains(HeaderPath(testDataDir.frameworksDir(),
|
||||
HeaderPath::FrameworkPath)));
|
||||
}
|
||||
|
||||
/// Check: Frameworks headers are resolved.
|
||||
@@ -254,12 +255,15 @@ void CppToolsPlugin::test_modelmanager_framework_headers()
|
||||
ProjectInfo pi = mm->projectInfo(project);
|
||||
QCOMPARE(pi.project().data(), project);
|
||||
|
||||
typedef ProjectPart::HeaderPath HeaderPath;
|
||||
|
||||
ProjectPart::Ptr part(new ProjectPart);
|
||||
part->cxxVersion = ProjectPart::CXX98;
|
||||
part->qtVersion = ProjectPart::Qt5;
|
||||
part->projectDefines = QByteArray("#define OH_BEHAVE -1\n");
|
||||
part->includePaths << testDataDir.includeDir();
|
||||
part->frameworkPaths << testDataDir.frameworksDir();
|
||||
part->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath)
|
||||
<< HeaderPath(testDataDir.frameworksDir(false), HeaderPath::FrameworkPath);
|
||||
const QString &source = testDataDir.fileFromSourcesDir(
|
||||
_("test_modelmanager_framework_headers.cpp"));
|
||||
part->files << ProjectFile(source, ProjectFile::CXXSource);
|
||||
@@ -303,11 +307,14 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files()
|
||||
ProjectInfo pi = mm->projectInfo(project);
|
||||
QCOMPARE(pi.project().data(), project);
|
||||
|
||||
typedef ProjectPart::HeaderPath HeaderPath;
|
||||
|
||||
ProjectPart::Ptr part(new ProjectPart);
|
||||
part->cxxVersion = ProjectPart::CXX98;
|
||||
part->qtVersion = ProjectPart::Qt5;
|
||||
part->projectDefines = QByteArray("#define OH_BEHAVE -1\n");
|
||||
part->includePaths = QStringList() << testDataDir.includeDir(false);
|
||||
part->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath);
|
||||
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
|
||||
pi.appendProjectPart(part);
|
||||
|
||||
@@ -806,6 +813,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
|
||||
|
||||
Project *project = helper.createProject(_("test_modelmanager_defines_per_project"));
|
||||
|
||||
typedef ProjectPart::HeaderPath HeaderPath;
|
||||
|
||||
ProjectPart::Ptr part1(new ProjectPart);
|
||||
part1->projectFile = QLatin1String("project1.projectfile");
|
||||
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
|
||||
@@ -813,7 +822,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
|
||||
part1->cxxVersion = ProjectPart::CXX11;
|
||||
part1->qtVersion = ProjectPart::NoQt;
|
||||
part1->projectDefines = QByteArray("#define SUB1\n");
|
||||
part1->includePaths = QStringList() << testDataDirectory.includeDir(false);
|
||||
part1->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath);
|
||||
|
||||
ProjectPart::Ptr part2(new ProjectPart);
|
||||
part2->projectFile = QLatin1String("project1.projectfile");
|
||||
@@ -822,7 +832,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
|
||||
part2->cxxVersion = ProjectPart::CXX11;
|
||||
part2->qtVersion = ProjectPart::NoQt;
|
||||
part2->projectDefines = QByteArray("#define SUB2\n");
|
||||
part2->includePaths = QStringList() << testDataDirectory.includeDir(false);
|
||||
part2->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath);
|
||||
|
||||
ProjectInfo pi = mm->projectInfo(project);
|
||||
pi.appendProjectPart(part1);
|
||||
@@ -877,6 +888,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch()
|
||||
|
||||
Project *project = helper.createProject(_("test_modelmanager_defines_per_project_pch"));
|
||||
|
||||
typedef ProjectPart::HeaderPath HeaderPath;
|
||||
|
||||
ProjectPart::Ptr part1(new ProjectPart);
|
||||
part1->projectFile = QLatin1String("project1.projectfile");
|
||||
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
|
||||
@@ -884,7 +897,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch()
|
||||
part1->cxxVersion = ProjectPart::CXX11;
|
||||
part1->qtVersion = ProjectPart::NoQt;
|
||||
part1->precompiledHeaders.append(pch1File);
|
||||
part1->includePaths = QStringList() << testDataDirectory.includeDir(false);
|
||||
part1->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath);
|
||||
|
||||
ProjectPart::Ptr part2(new ProjectPart);
|
||||
part2->projectFile = QLatin1String("project2.projectfile");
|
||||
@@ -893,7 +907,8 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch()
|
||||
part2->cxxVersion = ProjectPart::CXX11;
|
||||
part2->qtVersion = ProjectPart::NoQt;
|
||||
part2->precompiledHeaders.append(pch2File);
|
||||
part2->includePaths = QStringList() << testDataDirectory.includeDir(false);
|
||||
part2->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath);
|
||||
|
||||
ProjectInfo pi = mm->projectInfo(project);
|
||||
pi.appendProjectPart(part1);
|
||||
@@ -949,19 +964,23 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
|
||||
|
||||
Project *project = helper.createProject(_("test_modelmanager_defines_per_editor"));
|
||||
|
||||
typedef ProjectPart::HeaderPath HeaderPath;
|
||||
|
||||
ProjectPart::Ptr part1(new ProjectPart);
|
||||
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
|
||||
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
|
||||
part1->cxxVersion = ProjectPart::CXX11;
|
||||
part1->qtVersion = ProjectPart::NoQt;
|
||||
part1->includePaths = QStringList() << testDataDirectory.includeDir(false);
|
||||
part1->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath);
|
||||
|
||||
ProjectPart::Ptr part2(new ProjectPart);
|
||||
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
|
||||
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
|
||||
part2->cxxVersion = ProjectPart::CXX11;
|
||||
part2->qtVersion = ProjectPart::NoQt;
|
||||
part2->includePaths = QStringList() << testDataDirectory.includeDir(false);
|
||||
part2->headerPaths = QList<HeaderPath>()
|
||||
<< HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath);
|
||||
|
||||
ProjectInfo pi = mm->projectInfo(project);
|
||||
pi.appendProjectPart(part1);
|
||||
|
||||
@@ -154,12 +154,12 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc,
|
||||
cWarningFlags = tc->warningFlags(cflags);
|
||||
cxxWarningFlags = tc->warningFlags(cxxflags);
|
||||
|
||||
const QList<HeaderPath> headers = tc->systemHeaderPaths(cxxflags, sysRoot);
|
||||
foreach (const HeaderPath &header, headers)
|
||||
if (header.kind() == HeaderPath::FrameworkHeaderPath)
|
||||
frameworkPaths << header.path();
|
||||
else
|
||||
includePaths << header.path();
|
||||
const QList<ProjectExplorer::HeaderPath> headers = tc->systemHeaderPaths(cxxflags, sysRoot);
|
||||
foreach (const ProjectExplorer::HeaderPath &header, headers) {
|
||||
headerPaths << HeaderPath(header.path(),
|
||||
header.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath
|
||||
? HeaderPath::FrameworkPath : HeaderPath::IncludePath);
|
||||
}
|
||||
|
||||
toolchainDefines = tc->predefinedMacros(cxxflags);
|
||||
}
|
||||
@@ -187,8 +187,7 @@ CppModelManagerInterface *CppModelManagerInterface::instance()
|
||||
void CppModelManagerInterface::ProjectInfo::clearProjectParts()
|
||||
{
|
||||
m_projectParts.clear();
|
||||
m_includePaths.clear();
|
||||
m_frameworkPaths.clear();
|
||||
m_headerPaths.clear();
|
||||
m_sourceFiles.clear();
|
||||
m_defines.clear();
|
||||
}
|
||||
@@ -200,17 +199,16 @@ void CppModelManagerInterface::ProjectInfo::appendProjectPart(const ProjectPart:
|
||||
|
||||
m_projectParts.append(part);
|
||||
|
||||
// Update include paths
|
||||
QSet<QString> incs = QSet<QString>::fromList(m_includePaths);
|
||||
foreach (const QString &ins, part->includePaths)
|
||||
incs.insert(ins);
|
||||
m_includePaths = incs.toList();
|
||||
typedef ProjectPart::HeaderPath HeaderPath;
|
||||
|
||||
// Update framework paths
|
||||
QSet<QString> frms = QSet<QString>::fromList(m_frameworkPaths);
|
||||
foreach (const QString &frm, part->frameworkPaths)
|
||||
frms.insert(frm);
|
||||
m_frameworkPaths = frms.toList();
|
||||
// Update header paths
|
||||
QSet<HeaderPath> incs = QSet<HeaderPath>::fromList(m_headerPaths);
|
||||
foreach (const HeaderPath &hp, part->headerPaths) {
|
||||
if (!incs.contains(hp)) {
|
||||
incs.insert(hp);
|
||||
m_headerPaths += hp;
|
||||
}
|
||||
}
|
||||
|
||||
// Update source files
|
||||
QSet<QString> srcs = QSet<QString>::fromList(m_sourceFiles);
|
||||
|
||||
@@ -101,6 +101,27 @@ public:
|
||||
|
||||
typedef QSharedPointer<ProjectPart> Ptr;
|
||||
|
||||
struct HeaderPath {
|
||||
enum Type { InvalidPath, IncludePath, FrameworkPath };
|
||||
|
||||
public:
|
||||
QString path;
|
||||
Type type;
|
||||
|
||||
HeaderPath(): type(InvalidPath) {}
|
||||
HeaderPath(const QString &path, Type type): path(path), type(type) {}
|
||||
|
||||
bool isValid() const { return type != InvalidPath; }
|
||||
bool isFrameworkPath() const { return type == FrameworkPath; }
|
||||
|
||||
bool operator==(const HeaderPath &other) const
|
||||
{ return path == other.path && type == other.type; }
|
||||
|
||||
bool operator!=(const HeaderPath &other) const
|
||||
{ return !(*this == other); }
|
||||
};
|
||||
typedef QList<HeaderPath> HeaderPaths;
|
||||
|
||||
public:
|
||||
QString displayName;
|
||||
QString projectFile;
|
||||
@@ -109,8 +130,7 @@ public:
|
||||
QString projectConfigFile; // currently only used by the Generic Project Manager
|
||||
QByteArray projectDefines;
|
||||
QByteArray toolchainDefines;
|
||||
QStringList includePaths;
|
||||
QStringList frameworkPaths;
|
||||
QList<HeaderPath> headerPaths;
|
||||
QStringList precompiledHeaders;
|
||||
CVersion cVersion;
|
||||
CXXVersion cxxVersion;
|
||||
@@ -120,6 +140,9 @@ public:
|
||||
ProjectExplorer::ToolChain::WarningFlags cxxWarningFlags;
|
||||
};
|
||||
|
||||
inline uint qHash(const ProjectPart::HeaderPath &key, uint seed = 0)
|
||||
{ return ((qHash(key.path) << 2) | key.type) ^ seed; }
|
||||
|
||||
class CPPTOOLS_EXPORT CppModelManagerInterface : public CPlusPlus::CppModelManagerBase
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -159,11 +182,8 @@ public:
|
||||
void clearProjectParts();
|
||||
void appendProjectPart(const ProjectPart::Ptr &part);
|
||||
|
||||
const QStringList includePaths() const
|
||||
{ return m_includePaths; }
|
||||
|
||||
const QStringList frameworkPaths() const
|
||||
{ return m_frameworkPaths; }
|
||||
const ProjectPart::HeaderPaths headerPaths() const
|
||||
{ return m_headerPaths; }
|
||||
|
||||
const QStringList sourceFiles() const
|
||||
{ return m_sourceFiles; }
|
||||
@@ -175,8 +195,7 @@ public:
|
||||
QPointer<ProjectExplorer::Project> m_project;
|
||||
QList<ProjectPart::Ptr> m_projectParts;
|
||||
// The members below are (re)calculated from the project parts once a part is appended.
|
||||
QStringList m_includePaths;
|
||||
QStringList m_frameworkPaths;
|
||||
ProjectPart::HeaderPaths m_headerPaths;
|
||||
QStringList m_sourceFiles;
|
||||
QByteArray m_defines;
|
||||
};
|
||||
@@ -266,11 +285,10 @@ public:
|
||||
virtual void setIndexingSupport(CppTools::CppIndexingSupport *indexingSupport) = 0;
|
||||
virtual CppIndexingSupport *indexingSupport() = 0;
|
||||
|
||||
virtual void setIncludePaths(const QStringList &includePaths) = 0;
|
||||
virtual void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths) = 0;
|
||||
virtual void enableGarbageCollector(bool enable) = 0;
|
||||
|
||||
virtual QStringList includePaths() = 0;
|
||||
virtual QStringList frameworkPaths() = 0;
|
||||
virtual ProjectPart::HeaderPaths headerPaths() = 0;
|
||||
virtual QByteArray definedMacros() = 0;
|
||||
|
||||
signals:
|
||||
|
||||
@@ -57,8 +57,7 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
|
||||
CppModelManager *modelManager
|
||||
= dynamic_cast<CppModelManager *>(CppModelManagerInterface::instance());
|
||||
QByteArray configFile = modelManager->codeModelConfiguration();
|
||||
QStringList includePaths;
|
||||
QStringList frameworkPaths;
|
||||
ProjectPart::HeaderPaths headerPaths;
|
||||
QStringList precompiledHeaders;
|
||||
QString projectConfigFile;
|
||||
|
||||
@@ -72,8 +71,7 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
|
||||
if (m_projectPart) {
|
||||
configFile += m_projectPart->toolchainDefines;
|
||||
configFile += m_projectPart->projectDefines;
|
||||
includePaths = m_projectPart->includePaths;
|
||||
frameworkPaths = m_projectPart->frameworkPaths;
|
||||
headerPaths = m_projectPart->headerPaths;
|
||||
projectConfigFile = m_projectPart->projectConfigFile;
|
||||
if (m_usePrecompiledHeaders)
|
||||
precompiledHeaders = m_projectPart->precompiledHeaders;
|
||||
@@ -91,13 +89,8 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
|
||||
m_editorDefinesChangedSinceLastUpdate = false;
|
||||
}
|
||||
|
||||
if (includePaths != m_includePaths) {
|
||||
m_includePaths = includePaths;
|
||||
invalidateSnapshot = true;
|
||||
}
|
||||
|
||||
if (frameworkPaths != m_frameworkPaths) {
|
||||
m_frameworkPaths = frameworkPaths;
|
||||
if (headerPaths != m_headerPaths) {
|
||||
m_headerPaths = headerPaths;
|
||||
invalidateSnapshot = true;
|
||||
}
|
||||
|
||||
@@ -174,8 +167,7 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
|
||||
globalSnapshot.remove(fileInEditor());
|
||||
sourceProcessor.setGlobalSnapshot(globalSnapshot);
|
||||
sourceProcessor.setWorkingCopy(workingCopy);
|
||||
sourceProcessor.setIncludePaths(m_includePaths);
|
||||
sourceProcessor.setFrameworkPaths(m_frameworkPaths);
|
||||
sourceProcessor.setHeaderPaths(m_headerPaths);
|
||||
sourceProcessor.run(configurationFileName);
|
||||
if (!m_projectConfigFile.isEmpty())
|
||||
sourceProcessor.run(m_projectConfigFile);
|
||||
@@ -218,16 +210,10 @@ Snapshot SnapshotUpdater::snapshot() const
|
||||
return m_snapshot;
|
||||
}
|
||||
|
||||
QStringList SnapshotUpdater::includePaths() const
|
||||
ProjectPart::HeaderPaths SnapshotUpdater::headerPaths() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_includePaths;
|
||||
}
|
||||
|
||||
QStringList SnapshotUpdater::frameworkPaths() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_frameworkPaths;
|
||||
return m_headerPaths;
|
||||
}
|
||||
|
||||
ProjectPart::Ptr SnapshotUpdater::currentProjectPart() const
|
||||
|
||||
@@ -56,8 +56,7 @@ public:
|
||||
|
||||
CPlusPlus::Document::Ptr document() const;
|
||||
CPlusPlus::Snapshot snapshot() const;
|
||||
QStringList includePaths() const;
|
||||
QStringList frameworkPaths() const;
|
||||
ProjectPart::HeaderPaths headerPaths() const;
|
||||
|
||||
ProjectPart::Ptr currentProjectPart() const;
|
||||
void setProjectPart(ProjectPart::Ptr projectPart);
|
||||
@@ -76,8 +75,7 @@ private:
|
||||
QByteArray m_configFile;
|
||||
bool m_editorDefinesChangedSinceLastUpdate;
|
||||
QByteArray m_editorDefines;
|
||||
QStringList m_includePaths;
|
||||
QStringList m_frameworkPaths;
|
||||
ProjectPart::HeaderPaths m_headerPaths;
|
||||
QString m_projectConfigFile;
|
||||
QStringList m_precompiledHeaders;
|
||||
CPlusPlus::Snapshot m_snapshot;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/textfileformat.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
@@ -98,38 +99,20 @@ void CppSourceProcessor::setRevision(unsigned revision)
|
||||
void CppSourceProcessor::setWorkingCopy(const CppModelManagerInterface::WorkingCopy &workingCopy)
|
||||
{ m_workingCopy = workingCopy; }
|
||||
|
||||
void CppSourceProcessor::setIncludePaths(const QStringList &includePaths)
|
||||
void CppSourceProcessor::setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths)
|
||||
{
|
||||
m_includePaths.clear();
|
||||
m_headerPaths.clear();
|
||||
|
||||
for (int i = 0; i < includePaths.size(); ++i) {
|
||||
const QString &path = includePaths.at(i);
|
||||
for (int i = 0, ei = headerPaths.size(); i < ei; ++i) {
|
||||
const ProjectPart::HeaderPath &path = headerPaths.at(i);
|
||||
|
||||
if (Utils::HostOsInfo::isMacHost()) {
|
||||
if (i + 1 < includePaths.size() && path.endsWith(QLatin1String(".framework/Headers"))) {
|
||||
const QFileInfo pathInfo(path);
|
||||
const QFileInfo frameworkFileInfo(pathInfo.path());
|
||||
const QString frameworkName = frameworkFileInfo.baseName();
|
||||
|
||||
const QFileInfo nextIncludePath = includePaths.at(i + 1);
|
||||
if (nextIncludePath.fileName() == frameworkName) {
|
||||
// We got a QtXXX.framework/Headers followed by $QTDIR/include/QtXXX.
|
||||
// In this case we prefer to include files from $QTDIR/include/QtXXX.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_includePaths.append(cleanPath(path));
|
||||
if (path.type == ProjectPart::HeaderPath::IncludePath)
|
||||
m_headerPaths.append(ProjectPart::HeaderPath(cleanPath(path.path), path.type));
|
||||
else
|
||||
addFrameworkPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
void CppSourceProcessor::setFrameworkPaths(const QStringList &frameworkPaths)
|
||||
{
|
||||
m_frameworkPaths.clear();
|
||||
foreach (const QString &frameworkPath, frameworkPaths)
|
||||
addFrameworkPath(frameworkPath);
|
||||
}
|
||||
|
||||
// Add the given framework path, and expand private frameworks.
|
||||
//
|
||||
// Example:
|
||||
@@ -137,16 +120,19 @@ void CppSourceProcessor::setFrameworkPaths(const QStringList &frameworkPaths)
|
||||
// has private frameworks in:
|
||||
// <framework-path>/ApplicationServices.framework/Frameworks
|
||||
// if the "Frameworks" folder exists inside the top level framework.
|
||||
void CppSourceProcessor::addFrameworkPath(const QString &frameworkPath)
|
||||
void CppSourceProcessor::addFrameworkPath(const ProjectPart::HeaderPath &frameworkPath)
|
||||
{
|
||||
QTC_ASSERT(frameworkPath.isFrameworkPath(), return);
|
||||
|
||||
// The algorithm below is a bit too eager, but that's because we're not getting
|
||||
// in the frameworks we're linking against. If we would have that, then we could
|
||||
// add only those private frameworks.
|
||||
const QString cleanFrameworkPath = cleanPath(frameworkPath);
|
||||
if (!m_frameworkPaths.contains(cleanFrameworkPath))
|
||||
m_frameworkPaths.append(cleanFrameworkPath);
|
||||
const ProjectPart::HeaderPath cleanFrameworkPath(cleanPath(frameworkPath.path),
|
||||
frameworkPath.type);
|
||||
if (!m_headerPaths.contains(cleanFrameworkPath))
|
||||
m_headerPaths.append(cleanFrameworkPath);
|
||||
|
||||
const QDir frameworkDir(cleanFrameworkPath);
|
||||
const QDir frameworkDir(cleanFrameworkPath.path);
|
||||
const QStringList filter = QStringList() << QLatin1String("*.framework");
|
||||
foreach (const QFileInfo &framework, frameworkDir.entryInfoList(filter)) {
|
||||
if (!framework.isDir())
|
||||
@@ -154,7 +140,8 @@ void CppSourceProcessor::addFrameworkPath(const QString &frameworkPath)
|
||||
const QFileInfo privateFrameworks(framework.absoluteFilePath(),
|
||||
QLatin1String("Frameworks"));
|
||||
if (privateFrameworks.exists() && privateFrameworks.isDir())
|
||||
addFrameworkPath(privateFrameworks.absoluteFilePath());
|
||||
addFrameworkPath(ProjectPart::HeaderPath(privateFrameworks.absoluteFilePath(),
|
||||
frameworkPath.type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,8 +246,10 @@ QString CppSourceProcessor::resolveFile_helper(const QString &fileName, IncludeT
|
||||
// searching as if this would be a global include.
|
||||
}
|
||||
|
||||
foreach (const QString &includePath, m_includePaths) {
|
||||
const QString path = includePath + fileName;
|
||||
foreach (const ProjectPart::HeaderPath &headerPath, m_headerPaths) {
|
||||
if (headerPath.isFrameworkPath())
|
||||
continue;
|
||||
const QString path = headerPath.path + fileName;
|
||||
if (m_workingCopy.contains(path) || checkFile(path))
|
||||
return path;
|
||||
}
|
||||
@@ -271,8 +260,10 @@ QString CppSourceProcessor::resolveFile_helper(const QString &fileName, IncludeT
|
||||
const QString name = frameworkName + QLatin1String(".framework/Headers/")
|
||||
+ fileName.mid(index + 1);
|
||||
|
||||
foreach (const QString &frameworkPath, m_frameworkPaths) {
|
||||
const QString path = frameworkPath + name;
|
||||
foreach (const ProjectPart::HeaderPath &headerPath, m_headerPaths) {
|
||||
if (!headerPath.isFrameworkPath())
|
||||
continue;
|
||||
const QString path = headerPath.path + name;
|
||||
if (checkFile(path))
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@ public:
|
||||
|
||||
void setRevision(unsigned revision);
|
||||
void setWorkingCopy(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy);
|
||||
void setIncludePaths(const QStringList &includePaths);
|
||||
void setFrameworkPaths(const QStringList &frameworkPaths);
|
||||
void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths);
|
||||
void setTodo(const QStringList &files);
|
||||
|
||||
void run(const QString &fileName);
|
||||
@@ -54,7 +53,7 @@ public:
|
||||
void setGlobalSnapshot(const CPlusPlus::Snapshot &snapshot) { m_globalSnapshot = snapshot; }
|
||||
|
||||
private:
|
||||
void addFrameworkPath(const QString &frameworkPath);
|
||||
void addFrameworkPath(const ProjectPart::HeaderPath &frameworkPath);
|
||||
|
||||
CPlusPlus::Document::Ptr switchCurrentDocument(CPlusPlus::Document::Ptr doc);
|
||||
|
||||
@@ -90,9 +89,8 @@ private:
|
||||
bool m_dumpFileNameWhileParsing;
|
||||
CPlusPlus::Environment m_env;
|
||||
CPlusPlus::Preprocessor m_preprocess;
|
||||
QStringList m_includePaths;
|
||||
ProjectPart::HeaderPaths m_headerPaths;
|
||||
CppTools::CppModelManagerInterface::WorkingCopy m_workingCopy;
|
||||
QStringList m_frameworkPaths;
|
||||
QSet<QString> m_included;
|
||||
CPlusPlus::Document::Ptr m_currentDoc;
|
||||
QSet<QString> m_todo;
|
||||
|
||||
@@ -71,7 +71,9 @@ public:
|
||||
|
||||
QScopedPointer<CppSourceProcessor> sourceProcessor(
|
||||
CppModelManager::createSourceProcessor());
|
||||
sourceProcessor->setIncludePaths(QStringList(TestIncludePaths::directoryOfTestFile()));
|
||||
const ProjectPart::HeaderPath hp(TestIncludePaths::directoryOfTestFile(),
|
||||
ProjectPart::HeaderPath::IncludePath);
|
||||
sourceProcessor->setHeaderPaths(ProjectPart::HeaderPaths() << hp);
|
||||
sourceProcessor->run(fileName);
|
||||
|
||||
Document::Ptr document = m_cmm->document(fileName);
|
||||
|
||||
@@ -128,6 +128,7 @@ equals(TEST, 1) {
|
||||
cppcodegen_test.cpp \
|
||||
cppcompletion_test.cpp \
|
||||
cppheadersource_test.cpp \
|
||||
cpplocalsymbols_test.cpp \
|
||||
cpplocatorfilter_test.cpp \
|
||||
cppmodelmanager_test.cpp \
|
||||
cpppointerdeclarationformatter_test.cpp \
|
||||
|
||||
@@ -87,6 +87,7 @@ QtcPlugin {
|
||||
"cppcodegen_test.cpp",
|
||||
"cppcompletion_test.cpp",
|
||||
"cppheadersource_test.cpp",
|
||||
"cpplocalsymbols_test.cpp",
|
||||
"cpplocatorfilter_test.cpp",
|
||||
"cppmodelmanager_test.cpp",
|
||||
"cpppointerdeclarationformatter_test.cpp",
|
||||
|
||||
@@ -162,6 +162,9 @@ private slots:
|
||||
void test_typehierarchy_data();
|
||||
void test_typehierarchy();
|
||||
|
||||
void test_cpplocalsymbols_data();
|
||||
void test_cpplocalsymbols();
|
||||
|
||||
void test_includeGroups_detectIncludeGroupsByNewLines();
|
||||
void test_includeGroups_detectIncludeGroupsByIncludeDir();
|
||||
void test_includeGroups_detectIncludeGroupsByIncludeType();
|
||||
|
||||
@@ -518,7 +518,10 @@ static QList<Include> includesForSource(const QByteArray &source)
|
||||
CppModelManager *cmm = CppModelManager::instance();
|
||||
cmm->GC();
|
||||
QScopedPointer<CppSourceProcessor> sourceProcessor(CppModelManager::createSourceProcessor());
|
||||
sourceProcessor->setIncludePaths(QStringList(TestIncludePaths::globalIncludePath()));
|
||||
sourceProcessor->setHeaderPaths(ProjectPart::HeaderPaths()
|
||||
<< ProjectPart::HeaderPath(
|
||||
TestIncludePaths::globalIncludePath(),
|
||||
ProjectPart::HeaderPath::IncludePath));
|
||||
sourceProcessor->run(fileName);
|
||||
|
||||
Document::Ptr document = cmm->document(fileName);
|
||||
|
||||
@@ -87,8 +87,7 @@ void ModelManagerTestHelper::verifyClean()
|
||||
assert(mm);
|
||||
|
||||
QVERIFY(mm->projectInfos().isEmpty());
|
||||
QVERIFY(mm->includePaths().isEmpty());
|
||||
QVERIFY(mm->frameworkPaths().isEmpty());
|
||||
QVERIFY(mm->headerPaths().isEmpty());
|
||||
QVERIFY(mm->definedMacros().isEmpty());
|
||||
QVERIFY(mm->projectFiles().isEmpty());
|
||||
QVERIFY(mm->snapshot().isEmpty());
|
||||
|
||||
Reference in New Issue
Block a user