Merge remote-tracking branch 'origin/3.4'

Conflicts:
	src/libs/extensionsystem/pluginview.cpp

Change-Id: I410156c1003d5dc81e915110c6d432bcd71da010
This commit is contained in:
Eike Ziller
2015-05-07 14:42:46 +02:00
52 changed files with 3508 additions and 924 deletions

View File

@@ -61,9 +61,6 @@ namespace {
class ParseParams
{
public:
ParseParams() : revision(0) {}
int revision;
ProjectPart::HeaderPaths headerPaths;
WorkingCopy workingCopy;
QSet<QString> sourceFiles;
@@ -189,7 +186,6 @@ void indexFindErrors(QFutureInterface<void> &future, const ParseParams params)
void index(QFutureInterface<void> &future, const ParseParams params)
{
QScopedPointer<CppSourceProcessor> sourceProcessor(CppModelManager::createSourceProcessor());
sourceProcessor->setRevision(params.revision);
sourceProcessor->setHeaderPaths(params.headerPaths);
sourceProcessor->setWorkingCopy(params.workingCopy);
@@ -347,7 +343,6 @@ private:
} // anonymous namespace
BuiltinIndexingSupport::BuiltinIndexingSupport()
: m_revision(0)
{
m_synchronizer.setCancelOnWait(true);
}
@@ -361,7 +356,6 @@ QFuture<void> BuiltinIndexingSupport::refreshSourceFiles(const QSet<QString> &so
CppModelManager *mgr = CppModelManager::instance();
ParseParams params;
params.revision = ++m_revision;
params.headerPaths = mgr->headerPaths();
params.workingCopy = mgr->workingCopy();
params.sourceFiles = sourceFiles;

View File

@@ -54,7 +54,6 @@ public:
private:
QFutureSynchronizer<void> m_synchronizer;
unsigned m_revision;
};
} // namespace Internal

View File

@@ -168,6 +168,8 @@ bool isProbablyGlobalCompletion(const QStringList &list)
+ (T_FIRST_OBJC_AT_KEYWORD - T_FIRST_KEYWORD);
return list.size() >= numberOfPrimitivesAndBasicKeywords
&& list.contains(QLatin1String("override"))
&& list.contains(QLatin1String("final"))
&& list.contains(QLatin1String("if"))
&& list.contains(QLatin1String("bool"));
}
@@ -340,25 +342,48 @@ void CppToolsPlugin::test_global_completion_data()
{
QTest::addColumn<QByteArray>("code");
QTest::addColumn<QByteArray>("prefix");
QTest::addColumn<QStringList>("requiredCompletionItems");
// Check that special completion after '&' for Qt5 signal/slots does not
// interfere global completion after '&'
QTest::newRow("global completion after & in return expression")
<< _("void f() { foo(myObject, @); }\n")
<< _("&");
<< _("&")
<< QStringList();
QTest::newRow("global completion after & in function argument")
<< _("int f() { return @; }\n")
<< _("&");
<< _("&")
<< QStringList();
// Check global completion after one line comments
const QByteArray codeTemplate = "int myGlobal;\n"
"<REPLACEMENT>\n"
"@\n";
const QStringList replacements = QStringList()
<< QLatin1String("// text")
<< QLatin1String("// text.")
<< QLatin1String("/// text")
<< QLatin1String("/// text.")
;
foreach (const QString &replacement, replacements) {
QByteArray code = codeTemplate;
code.replace("<REPLACEMENT>", replacement.toUtf8());
const QByteArray tag = _("completion after comment: ") + replacement.toUtf8();
QTest::newRow(tag) << code << QByteArray() << QStringList(QLatin1String("myGlobal"));
}
}
void CppToolsPlugin::test_global_completion()
{
QFETCH(QByteArray, code);
QFETCH(QByteArray, prefix);
QFETCH(QStringList, requiredCompletionItems);
CompletionTestCase test(code, prefix);
QVERIFY(test.succeededSoFar());
QVERIFY(isProbablyGlobalCompletion(test.getCompletions()));
const QStringList completions = test.getCompletions();
QVERIFY(isProbablyGlobalCompletion(completions));
QVERIFY(completions.toSet().contains(requiredCompletionItems.toSet()));
}
static void enumTestCase(const QByteArray &tag, const QByteArray &source,

View File

@@ -974,8 +974,9 @@ int InternalCppCompletionAssistProcessor::startOfOperator(int pos,
start = pos;
}
// Don't complete in comments or strings, but still check for include completion
else if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT) ||
(tk.isLiteral() && (*kind != T_STRING_LITERAL
else if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT)
|| tk.is(T_CPP_DOXY_COMMENT) || tk.is(T_DOXY_COMMENT)
|| (tk.isLiteral() && (*kind != T_STRING_LITERAL
&& *kind != T_ANGLE_STRING_LITERAL
&& *kind != T_SLASH
&& *kind != T_DOT))) {
@@ -1936,6 +1937,12 @@ void InternalCppCompletionAssistProcessor::addKeywords()
// primitive type completion items.
for (int i = T_FIRST_PRIMITIVE; i <= T_LAST_PRIMITIVE; ++i)
addCompletionItem(QLatin1String(Token::name(i)), m_icons.keywordIcon(), KeywordsOrder);
// "Identifiers with special meaning"
if (m_interface->languageFeatures().cxx11Enabled) {
addCompletionItem(QLatin1String("override"), m_icons.keywordIcon(), KeywordsOrder);
addCompletionItem(QLatin1String("final"), m_icons.keywordIcon(), KeywordsOrder);
}
}
void InternalCppCompletionAssistProcessor::addMacros(const QString &fileName,

View File

@@ -232,6 +232,11 @@ CppSourceProcessor *CppModelManager::createSourceProcessor()
{
CppModelManager *that = instance();
return new CppSourceProcessor(that->snapshot(), [that](const Document::Ptr &doc) {
const Document::Ptr previousDocument = that->document(doc->fileName());
const unsigned newRevision = previousDocument.isNull()
? 1U
: previousDocument->revision() + 1;
doc->setRevision(newRevision);
that->emitDocumentUpdated(doc);
doc->releaseSourceAndAST();
});

View File

@@ -48,6 +48,10 @@
#include <QDebug>
#include <QtTest>
#define VERIFY_DOCUMENT_REVISION(document, expectedRevision) \
QVERIFY(document); \
QCOMPARE(document->revision(), expectedRevision);
using namespace CppTools;
using namespace CppTools::Internal;
using namespace CppTools::Tests;
@@ -172,6 +176,15 @@ static QSet<QString> updateProjectInfo(CppModelManager *modelManager, ModelManag
return helper->waitForRefreshedSourceFiles();
}
void waitForProcessedEditorDocument(const QString &filePath)
{
CppEditorDocumentHandle *editorDocument
= CppModelManager::instance()->cppEditorDocument(filePath);
QVERIFY(editorDocument);
while (editorDocument->processor()->isParserRunning())
QCoreApplication::processEvents();
}
} // anonymous namespace
/// Check: The preprocessor cleans include and framework paths.
@@ -1107,3 +1120,45 @@ void CppToolsPlugin::test_modelmanager_renameIncludes()
foreach (const QString &sourceFile, sourceFiles)
QCOMPARE(snapshot.allIncludesForDocument(sourceFile), QSet<QString>() << newHeader);
}
void CppToolsPlugin::test_modelmanager_documentsAndRevisions()
{
TestCase helper;
// Index two files
const MyTestDataDir testDir(_("testdata_project1"));
const QString filePath1 = testDir.file(QLatin1String("foo.h"));
const QString filePath2 = testDir.file(QLatin1String("foo.cpp"));
const QSet<QString> filesToIndex = QSet<QString>() << filePath1 << filePath2;
QVERIFY(TestCase::parseFiles(filesToIndex));
CppModelManager *modelManager = CppModelManager::instance();
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 1U);
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 1U);
// Open editor for file 1
TextEditor::BaseTextEditor *editor1;
QVERIFY(helper.openBaseTextEditor(filePath1, &editor1));
helper.closeEditorAtEndOfTestCase(editor1);
waitForProcessedEditorDocument(filePath1);
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 2U);
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 1U);
// Index again
QVERIFY(TestCase::parseFiles(filesToIndex));
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 3U);
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 2U);
// Open editor for file 2
TextEditor::BaseTextEditor *editor2;
QVERIFY(helper.openBaseTextEditor(filePath2, &editor2));
helper.closeEditorAtEndOfTestCase(editor2);
waitForProcessedEditorDocument(filePath2);
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 3U);
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 3U);
// Index again
QVERIFY(TestCase::parseFiles(filesToIndex));
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 4U);
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 4U);
}

View File

@@ -117,7 +117,6 @@ CppSourceProcessor::CppSourceProcessor(const Snapshot &snapshot, DocumentCallbac
m_documentFinished(documentFinished),
m_preprocess(this, &m_env),
m_languageFeatures(LanguageFeatures::defaultFeatures()),
m_revision(0),
m_defaultCodec(Core::EditorManager::defaultTextCodec())
{
m_preprocess.setKeepComments(true);
@@ -126,9 +125,6 @@ CppSourceProcessor::CppSourceProcessor(const Snapshot &snapshot, DocumentCallbac
CppSourceProcessor::~CppSourceProcessor()
{ }
void CppSourceProcessor::setRevision(unsigned revision)
{ m_revision = revision; }
void CppSourceProcessor::setWorkingCopy(const WorkingCopy &workingCopy)
{ m_workingCopy = workingCopy; }
@@ -470,7 +466,6 @@ void CppSourceProcessor::sourceNeeded(unsigned line, const QString &fileName, In
qCDebug(log) << "Parsing:" << absoluteFileName << "contents:" << contents.size() << "bytes";
Document::Ptr document = Document::create(absoluteFileName);
document->setRevision(m_revision);
document->setEditorRevision(editorRevision);
document->setLanguageFeatures(m_languageFeatures);
foreach (const QString &include, initialIncludes) {

View File

@@ -65,7 +65,6 @@ public:
CppSourceProcessor(const CPlusPlus::Snapshot &snapshot, DocumentCallback documentFinished);
~CppSourceProcessor();
void setRevision(unsigned revision);
void setWorkingCopy(const CppTools::WorkingCopy &workingCopy);
void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths);
void setLanguageFeatures(CPlusPlus::LanguageFeatures languageFeatures);
@@ -124,7 +123,6 @@ private:
CPlusPlus::Document::Ptr m_currentDoc;
QSet<QString> m_todo;
QSet<QString> m_processed;
unsigned m_revision;
QHash<QString, QString> m_fileNameCache;
QTextCodec *m_defaultCodec;
};

View File

@@ -158,6 +158,7 @@ private slots:
void test_modelmanager_updateEditorsAfterProjectUpdate();
void test_modelmanager_precompiled_headers();
void test_modelmanager_renameIncludes();
void test_modelmanager_documentsAndRevisions();
void test_cpplocatorfilters_CppLocatorFilter();
void test_cpplocatorfilters_CppLocatorFilter_data();