CppTools: Fix global completion after "/// text."

Like for other comments, don't try member completion if the doxygen
comment ends with a dot.

Task-number: QTCREATORBUG-8597
Change-Id: I2d5204ba8f45fc9ee94e285a907364cc722e62c7
Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2015-04-23 12:01:54 +02:00
parent 7697bd4b6f
commit cea5d886d8
3 changed files with 33 additions and 7 deletions

View File

@@ -680,6 +680,7 @@ int ClangCompletionAssistProcessor::startCompletionHelper()
return startCompletionInternal(fileName, line, column, endOfOperator); return startCompletionInternal(fileName, line, column, endOfOperator);
} }
// TODO: Extract duplicated logic from InternalCppCompletionAssistProcessor::startOfOperator
int ClangCompletionAssistProcessor::startOfOperator(int pos, int ClangCompletionAssistProcessor::startOfOperator(int pos,
unsigned *kind, unsigned *kind,
bool wantFunctionCall) const bool wantFunctionCall) const
@@ -724,8 +725,9 @@ int ClangCompletionAssistProcessor::startOfOperator(int pos,
start = pos; start = pos;
} }
// Don't complete in comments or strings, but still check for include completion // Don't complete in comments or strings, but still check for include completion
else if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT) || else if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT)
(tk.isLiteral() && (*kind != T_STRING_LITERAL || tk.is(T_CPP_DOXY_COMMENT) || tk.is(T_DOXY_COMMENT)
|| (tk.isLiteral() && (*kind != T_STRING_LITERAL
&& *kind != T_ANGLE_STRING_LITERAL && *kind != T_ANGLE_STRING_LITERAL
&& *kind != T_SLASH))) { && *kind != T_SLASH))) {
*kind = T_EOF_SYMBOL; *kind = T_EOF_SYMBOL;

View File

@@ -341,25 +341,48 @@ void CppToolsPlugin::test_global_completion_data()
{ {
QTest::addColumn<QByteArray>("code"); QTest::addColumn<QByteArray>("code");
QTest::addColumn<QByteArray>("prefix"); QTest::addColumn<QByteArray>("prefix");
QTest::addColumn<QStringList>("requiredCompletionItems");
// Check that special completion after '&' for Qt5 signal/slots does not // Check that special completion after '&' for Qt5 signal/slots does not
// interfere global completion after '&' // interfere global completion after '&'
QTest::newRow("global completion after & in return expression") QTest::newRow("global completion after & in return expression")
<< _("void f() { foo(myObject, @); }\n") << _("void f() { foo(myObject, @); }\n")
<< _("&"); << _("&")
<< QStringList();
QTest::newRow("global completion after & in function argument") QTest::newRow("global completion after & in function argument")
<< _("int f() { return @; }\n") << _("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() void CppToolsPlugin::test_global_completion()
{ {
QFETCH(QByteArray, code); QFETCH(QByteArray, code);
QFETCH(QByteArray, prefix); QFETCH(QByteArray, prefix);
QFETCH(QStringList, requiredCompletionItems);
CompletionTestCase test(code, prefix); CompletionTestCase test(code, prefix);
QVERIFY(test.succeededSoFar()); 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, static void enumTestCase(const QByteArray &tag, const QByteArray &source,

View File

@@ -974,8 +974,9 @@ int InternalCppCompletionAssistProcessor::startOfOperator(int pos,
start = pos; start = pos;
} }
// Don't complete in comments or strings, but still check for include completion // Don't complete in comments or strings, but still check for include completion
else if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT) || else if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT)
(tk.isLiteral() && (*kind != T_STRING_LITERAL || tk.is(T_CPP_DOXY_COMMENT) || tk.is(T_DOXY_COMMENT)
|| (tk.isLiteral() && (*kind != T_STRING_LITERAL
&& *kind != T_ANGLE_STRING_LITERAL && *kind != T_ANGLE_STRING_LITERAL
&& *kind != T_SLASH && *kind != T_SLASH
&& *kind != T_DOT))) { && *kind != T_DOT))) {