diff options
author | Nikolai Kosjar <nikolai.kosjar@digia.com> | 2013-07-25 11:21:31 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@digia.com> | 2013-08-22 11:57:27 +0200 |
commit | fd9293dd0af0e8f253c0934ede60b72496ee0314 (patch) | |
tree | a06df33a43e1eaeddf12d14e863aa84031428c73 | |
parent | 2fe1fec16b82561f2e4371bebe1b6d2c29e8fb96 (diff) | |
download | qt-creator-fd9293dd0af0e8f253c0934ede60b72496ee0314.tar.gz |
CppTools: CppPreprocessor: Track also unresolved includes
Change-Id: Ia36e7e7142dbc030a428369ed04e76e70e8eef0b
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
-rw-r--r-- | src/libs/cplusplus/CppDocument.cpp | 13 | ||||
-rw-r--r-- | src/libs/cplusplus/CppDocument.h | 10 | ||||
-rw-r--r-- | src/libs/cplusplus/FastPreprocessor.cpp | 4 | ||||
-rw-r--r-- | src/libs/cplusplus/LookupContext.cpp | 2 | ||||
-rw-r--r-- | src/libs/cplusplus/SnapshotSymbolVisitor.cpp | 2 | ||||
-rw-r--r-- | src/libs/cplusplus/TypeOfExpression.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditor.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppelementevaluator.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfix_test.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfixes.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cpptools/cppchecksymbols.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cpptools/cppcompletionassist.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cpptools/cpppreprocessor.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cpptools/cpppreprocessor_test.cpp | 113 | ||||
-rw-r--r-- | src/plugins/cpptools/cpptools.pro | 5 | ||||
-rw-r--r-- | src/plugins/cpptools/cpptools.qbs | 5 | ||||
-rw-r--r-- | src/plugins/cpptools/cpptoolsplugin.h | 2 |
17 files changed, 152 insertions, 26 deletions
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 301019e909..fd299f7ca0 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -341,7 +341,7 @@ QString Document::fileName() const QStringList Document::includedFiles() const { QStringList files; - foreach (const Include &i, _includes) + foreach (const Include &i, _resolvedIncludes) files.append(i.resolvedFileName()); files.removeDuplicates(); return files; @@ -350,7 +350,10 @@ QStringList Document::includedFiles() const // This assumes to be called with a QDir::cleanPath cleaned fileName. void Document::addIncludeFile(const Document::Include &include) { - _includes.append(include); + if (include.resolvedFileName().isEmpty()) + _unresolvedIncludes.append(include); + else + _resolvedIncludes.append(include); } void Document::appendMacro(const Macro ¯o) @@ -740,7 +743,8 @@ Document::Ptr Snapshot::preprocessedDocument(const QString &source, const QStrin newDoc->_revision = thisDocument->_revision; newDoc->_editorRevision = thisDocument->_editorRevision; newDoc->_lastModified = thisDocument->_lastModified; - newDoc->_includes = thisDocument->_includes; + newDoc->_resolvedIncludes = thisDocument->_resolvedIncludes; + newDoc->_unresolvedIncludes = thisDocument->_unresolvedIncludes; } FastPreprocessor pp(*this); @@ -758,7 +762,8 @@ Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode, newDoc->_revision = thisDocument->_revision; newDoc->_editorRevision = thisDocument->_editorRevision; newDoc->_lastModified = thisDocument->_lastModified; - newDoc->_includes = thisDocument->_includes; + newDoc->_resolvedIncludes = thisDocument->_resolvedIncludes; + newDoc->_unresolvedIncludes = thisDocument->_unresolvedIncludes; newDoc->_definedMacros = thisDocument->_definedMacros; newDoc->_macroUses = thisDocument->_macroUses; } diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 593d604c2b..980535bb4d 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -312,8 +312,11 @@ public: QStringList includedFiles() const; void addIncludeFile(const Include &include); - QList<Include> includes() const - { return _includes; } + QList<Include> resolvedIncludes() const + { return _resolvedIncludes; } + + QList<Include> unresolvedIncludes() const + { return _unresolvedIncludes; } QList<Block> skippedBlocks() const { return _skippedBlocks; } @@ -348,7 +351,8 @@ private: /// All messages generated during lexical/syntactic/semantic analysis. QList<DiagnosticMessage> _diagnosticMessages; - QList<Include> _includes; + QList<Include> _resolvedIncludes; + QList<Include> _unresolvedIncludes; QList<Macro> _definedMacros; QList<Block> _skippedBlocks; QList<MacroUse> _macroUses; diff --git a/src/libs/cplusplus/FastPreprocessor.cpp b/src/libs/cplusplus/FastPreprocessor.cpp index 7156b51f3d..70f271e13b 100644 --- a/src/libs/cplusplus/FastPreprocessor.cpp +++ b/src/libs/cplusplus/FastPreprocessor.cpp @@ -52,7 +52,7 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QString &source) _merged.insert(fileName); mergeEnvironment(Preprocessor::configurationFileName); - foreach (const Document::Include &i, doc->includes()) + foreach (const Document::Include &i, doc->resolvedIncludes()) mergeEnvironment(i.resolvedFileName()); } @@ -78,7 +78,7 @@ void FastPreprocessor::mergeEnvironment(const QString &fileName) _merged.insert(fileName); if (Document::Ptr doc = _snapshot.document(fileName)) { - foreach (const Document::Include &i, doc->includes()) + foreach (const Document::Include &i, doc->resolvedIncludes()) mergeEnvironment(i.resolvedFileName()); _env.addMacros(doc->definedMacros()); diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index d6a5ecb865..cf9f2be7e1 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -1454,7 +1454,7 @@ void CreateBindings::process(Document::Ptr doc) if (! _processed.contains(globalNamespace)) { _processed.insert(globalNamespace); - foreach (const Document::Include &i, doc->includes()) { + foreach (const Document::Include &i, doc->resolvedIncludes()) { if (Document::Ptr incl = _snapshot.document(i.resolvedFileName())) process(incl); } diff --git a/src/libs/cplusplus/SnapshotSymbolVisitor.cpp b/src/libs/cplusplus/SnapshotSymbolVisitor.cpp index 9599607973..1406d778be 100644 --- a/src/libs/cplusplus/SnapshotSymbolVisitor.cpp +++ b/src/libs/cplusplus/SnapshotSymbolVisitor.cpp @@ -49,7 +49,7 @@ void SnapshotSymbolVisitor::accept(Document::Ptr doc, QSet<QString> *processed) if (doc && doc->globalNamespace() && ! processed->contains(doc->fileName())) { processed->insert(doc->fileName()); - foreach (const Document::Include &i, doc->includes()) { + foreach (const Document::Include &i, doc->resolvedIncludes()) { if (Document::Ptr incl = _snapshot.document(i.resolvedFileName())) accept(incl, processed); } diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp index 0808bf1a2a..01e9c8f7df 100644 --- a/src/libs/cplusplus/TypeOfExpression.cpp +++ b/src/libs/cplusplus/TypeOfExpression.cpp @@ -177,7 +177,7 @@ void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env, if (doc && ! processed->contains(doc->fileName())) { processed->insert(doc->fileName()); - foreach (const Document::Include &incl, doc->includes()) + foreach (const Document::Include &incl, doc->resolvedIncludes()) processEnvironment(m_snapshot.document(incl.resolvedFileName()), env, processed); foreach (const Macro ¯o, doc->definedMacros()) diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index e8cb40e6da..3e5cb74293 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1387,7 +1387,7 @@ CPPEditorWidget::Link CPPEditorWidget::findMacroLink(const QByteArray &name, } } - const QList<Document::Include> includes = doc->includes(); + const QList<Document::Include> includes = doc->resolvedIncludes(); for (int index = includes.size() - 1; index != -1; --index) { const Document::Include &i = includes.at(index); Link link = findMacroLink(name, snapshot.document(i.resolvedFileName()), snapshot, @@ -1519,7 +1519,7 @@ CPPEditorWidget::Link CPPEditorWidget::findLinkAt(const QTextCursor &cursor, boo // Handle include directives if (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)) { const unsigned lineno = cursor.blockNumber() + 1; - foreach (const Document::Include &incl, doc->includes()) { + foreach (const Document::Include &incl, doc->resolvedIncludes()) { if (incl.line() == lineno) { link.targetFileName = incl.resolvedFileName(); link.linkTextStart = beginOfToken + 1; diff --git a/src/plugins/cppeditor/cppelementevaluator.cpp b/src/plugins/cppeditor/cppelementevaluator.cpp index 12c584c26c..c7cc6dfa68 100644 --- a/src/plugins/cppeditor/cppelementevaluator.cpp +++ b/src/plugins/cppeditor/cppelementevaluator.cpp @@ -130,7 +130,7 @@ void CppElementEvaluator::checkDiagnosticMessage(int pos) bool CppElementEvaluator::matchIncludeFile(const CPlusPlus::Document::Ptr &document, unsigned line) { - foreach (const Document::Include &includeFile, document->includes()) { + foreach (const Document::Include &includeFile, document->resolvedIncludes()) { if (includeFile.line() == line) { m_element = QSharedPointer<CppElement>(new CppInclude(includeFile)); return true; diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 6ba36c2387..0960ade79e 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -1335,7 +1335,7 @@ QList<Include> includesForSource(const QByteArray &source) pp.run(fileName); Document::Ptr document = cmm->snapshot().document(fileName); - return document->includes(); + return document->resolvedIncludes(); } /// Check: Detection of include groups separated by new lines diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 19f6b5d9ef..e8611e7962 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -232,7 +232,7 @@ void insertNewIncludeDirective(const QString &include, CppRefactoringFilePtr fil { // Find optimal position using namespace IncludeUtils; - LineForNewIncludeDirective finder(file->document(), file->cppDocument()->includes(), + LineForNewIncludeDirective finder(file->document(), file->cppDocument()->resolvedIncludes(), LineForNewIncludeDirective::IgnoreMocIncludes, LineForNewIncludeDirective::AutoDetect); unsigned newLinesToPrepend = 0; @@ -1530,7 +1530,7 @@ public: fwdHeaders.insert(snapshot().document(headerFile)); foreach (Document::Ptr doc, snapshot()) { QFileInfo headerFileInfo(doc->fileName()); - if (doc->globalSymbolCount() == 0 && doc->includes().size() == 1) + if (doc->globalSymbolCount() == 0 && doc->resolvedIncludes().size() == 1) fwdHeaders.insert(doc); else if (headerFileInfo.suffix().isEmpty()) fwdHeaders.insert(doc); diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp index 8c7625e1e0..066e71f619 100644 --- a/src/plugins/cpptools/cppchecksymbols.cpp +++ b/src/plugins/cpptools/cppchecksymbols.cpp @@ -99,7 +99,7 @@ protected: if (!processed->contains(doc->globalNamespace())) { processed->insert(doc->globalNamespace()); - foreach (const Document::Include &i, doc->includes()) + foreach (const Document::Include &i, doc->resolvedIncludes()) process(_snapshot.document(i.resolvedFileName()), processed); _mainDocument = (doc == _doc); // ### improve diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index 4a1004aceb..bf5db57ff0 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -1732,7 +1732,7 @@ void CppCompletionAssistProcessor::addMacros_helper(const CPlusPlus::Snapshot &s processed->insert(doc->fileName()); - foreach (const Document::Include &i, doc->includes()) { + foreach (const Document::Include &i, doc->resolvedIncludes()) { addMacros_helper(snapshot, i.resolvedFileName(), processed, definedMacros); } diff --git a/src/plugins/cpptools/cpppreprocessor.cpp b/src/plugins/cpptools/cpppreprocessor.cpp index 1dae47621f..649d3d6bc9 100644 --- a/src/plugins/cpptools/cpppreprocessor.cpp +++ b/src/plugins/cpptools/cpppreprocessor.cpp @@ -332,7 +332,7 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc) m_processed.insert(fn); - foreach (const Document::Include &incl, doc->includes()) { + foreach (const Document::Include &incl, doc->resolvedIncludes()) { const QString includedFile = incl.resolvedFileName(); if (Document::Ptr includedDoc = m_snapshot.document(includedFile)) @@ -363,7 +363,7 @@ void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, Inclu QString absoluteFileName = resolveFile(fileName, type); absoluteFileName = QDir::cleanPath(absoluteFileName); - if (m_currentDoc && !absoluteFileName.isEmpty()) + if (m_currentDoc) m_currentDoc->addIncludeFile(Document::Include(fileName, absoluteFileName, line, type)); if (m_included.contains(absoluteFileName)) return; // we've already seen this file. diff --git a/src/plugins/cpptools/cpppreprocessor_test.cpp b/src/plugins/cpptools/cpppreprocessor_test.cpp new file mode 100644 index 0000000000..715fd984ce --- /dev/null +++ b/src/plugins/cpptools/cpppreprocessor_test.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 "cppmodelmanager.h" +#include "cpppreprocessertesthelper.h" +#include "cpppreprocessor.h" + +#include <cplusplus/CppDocument.h> +#include <utils/fileutils.h> + +#include <QtTest> + +using namespace CPlusPlus; +using namespace CppTools; +using namespace CppTools::Internal; + +typedef Document::Include Include; + +class SourcePreprocessor +{ +public: + SourcePreprocessor() + : m_cmm(CppModelManager::instance()) + { + cleanUp(); + } + + Document::Ptr run(const QByteArray &source) + { + const QString fileName = TestIncludePaths::directoryOfTestFile() + + QLatin1String("/file.cpp"); + Utils::FileSaver srcSaver(fileName); + srcSaver.write(source); + srcSaver.finalize(); + + CppPreprocessor pp((QPointer<CppModelManager>(m_cmm))); + pp.setIncludePaths(QStringList(TestIncludePaths::directoryOfTestFile())); + pp.run(fileName); + + return m_cmm->snapshot().document(fileName); + } + + ~SourcePreprocessor() + { + cleanUp(); + } + +private: + void cleanUp() + { + m_cmm->GC(); + QVERIFY(m_cmm->snapshot().isEmpty()); + } + +private: + CppModelManager *m_cmm; +}; + +void CppToolsPlugin::test_cpppreprocessor_includes() +{ + QByteArray source = + "#include \"header.h\"\n" + "#include \"notresolvable.h\"\n" + "\n" + ; + + SourcePreprocessor processor; + Document::Ptr document = processor.run(source); + QVERIFY(document); + + const QList<Document::Include> resolvedIncludes = document->resolvedIncludes(); + QVERIFY(resolvedIncludes.size() == 1); + QVERIFY(resolvedIncludes.at(0).type() == Client::IncludeLocal); + QCOMPARE(resolvedIncludes.at(0).unresolvedFileName(), QLatin1String("header.h")); + const QString expectedResolvedFileName + = TestIncludePaths::directoryOfTestFile() + QLatin1String("/header.h"); + QCOMPARE(resolvedIncludes.at(0).resolvedFileName(), expectedResolvedFileName); + + const QList<Document::Include> unresolvedIncludes = document->unresolvedIncludes(); + QVERIFY(unresolvedIncludes.size() == 1); + QVERIFY(unresolvedIncludes.at(0).type() == Client::IncludeLocal); + QCOMPARE(unresolvedIncludes.at(0).unresolvedFileName(), QLatin1String("notresolvable.h")); + QVERIFY(unresolvedIncludes.at(0).resolvedFileName().isEmpty()); +} + diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index 07d7862598..a8a1d39938 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -97,14 +97,15 @@ FORMS += completionsettingspage.ui \ equals(TEST, 1) { SOURCES += \ - cpppreprocessertesthelper.cpp \ cppcodegen_test.cpp \ cppcompletion_test.cpp \ cppmodelmanager_test.cpp \ modelmanagertesthelper.cpp \ cpppointerdeclarationformatter_test.cpp \ cpplocatorfilter_test.cpp \ - symbolsearcher_test.cpp + symbolsearcher_test.cpp \ + cpppreprocessor_test.cpp \ + cpppreprocessertesthelper.cpp HEADERS += \ cpppreprocessertesthelper.h \ diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 594a0321a0..a8b29fc06f 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -116,12 +116,13 @@ QtcPlugin { files: [ "cppcodegen_test.cpp", "cppcompletion_test.cpp", - "cpppreprocessertesthelper.cpp", "cpppreprocessertesthelper.h", "cppmodelmanager_test.cpp", "modelmanagertesthelper.cpp", "modelmanagertesthelper.h", "cpppointerdeclarationformatter_test.cpp", "cpplocatorfilter_test.cpp", - "symbolsearcher_test.cpp" + "symbolsearcher_test.cpp", + "cpppreprocessor_test.cpp", + "cpppreprocessertesthelper.cpp", "cpppreprocessertesthelper.h" ] cpp.defines: outer.concat(['SRCDIR="' + FileInfo.path(filePath) + '"']) diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 61f7cae310..6835e365d0 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -189,6 +189,8 @@ private slots: void test_format_pointerdeclaration_macros(); void test_format_pointerdeclaration_macros_data(); + void test_cpppreprocessor_includes(); + void test_modelmanager_paths_are_clean(); void test_modelmanager_framework_headers(); void test_modelmanager_refresh_also_includes_of_project_files(); |