Commit 57877cc1 authored by Nikolai Kosjar's avatar Nikolai Kosjar
Browse files

Clang: Workaround dot detection for arrow correction



...by explicitly checking for the dot in the source.

Task-number: QTCREATORBUG-15654
Change-Id: I4172e88a7fbb3015ef391daf13ded1f0002aab9c
Reviewed-by: default avatarMarco Bubke <marco.bubke@theqtcompany.com>
parent da27ea4d
......@@ -68,7 +68,7 @@ CodeCompletions CodeCompleter::complete(uint line, uint column)
translationUnit.cxUnsavedFiles(),
translationUnit.unsavedFilesCount());
if (results.hasNoResultsForDotCompletion())
if (results.hasNoResultsForDotCompletion() && hasDotAt(line, column - 1))
results = completeWithArrowInsteadOfDot(line, column);
return toCodeCompletions(results);
......@@ -95,6 +95,14 @@ ClangCodeCompleteResults CodeCompleter::complete(uint line,
options);
}
bool CodeCompleter::hasDotAt(uint line, uint column) const
{
const UnsavedFile &unsavedFile = translationUnit.unsavedFile();
const SourceLocation location = translationUnit.sourceLocationAtWithoutReparsing(line, column);
return unsavedFile.hasCharacterAt(location.offset(), '.');
}
ClangCodeCompleteResults CodeCompleter::completeWithArrowInsteadOfDot(uint line, uint column)
{
ClangCodeCompleteResults results;
......
......@@ -46,6 +46,9 @@ public:
CompletionCorrection neededCorrection() const;
public: // for tests
bool hasDotAt(uint line, uint column) const;
private:
ClangCodeCompleteResults complete(uint line,
uint column,
......
......@@ -65,6 +65,14 @@ const char *UnsavedFile::filePath() const
return cxUnsavedFile.Filename;
}
bool UnsavedFile::hasCharacterAt(uint position, char character) const
{
if (position < cxUnsavedFile.Length)
return cxUnsavedFile.Contents[position] == character;
return false;
}
bool UnsavedFile::replaceAt(uint position, uint length, const Utf8String &replacement)
{
if (position < cxUnsavedFile.Length) {
......
......@@ -51,6 +51,7 @@ public:
const char *filePath() const;
bool hasCharacterAt(uint position, char character) const;
bool replaceAt(uint position, uint length, const Utf8String &replacement);
CXUnsavedFile *data();
......
......@@ -148,6 +148,12 @@ protected:
readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForOnlyDot.cpp")),
true
};
ClangBackEnd::FileContainer noDotArrowCorrectionForColonColonFileContainer{
Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForColonColon.cpp"),
projectPart.projectPartId(),
readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForColonColon.cpp")),
true
};
};
Utf8String CodeCompleter::readFileContent(const QString &fileName)
......@@ -295,6 +301,22 @@ TEST_F(CodeCompleter, ArrowCompletion)
ClangBackEnd::CompletionCorrection::NoCorrection);
}
TEST_F(CodeCompleter, HasDotAt)
{
auto myCompleter = setupCompleter(dotArrowCorrectionForPointerFileContainer);
ASSERT_TRUE(myCompleter.hasDotAt(5, 8));
}
TEST_F(CodeCompleter, HasNoDotAtDueToMissingUnsavedFile)
{
const ClangBackEnd::FileContainer fileContainer = dotArrowCorrectionForPointerFileContainer;
translationUnits.create({fileContainer});
ClangBackEnd::CodeCompleter myCompleter(translationUnits.translationUnit(fileContainer));
ASSERT_FALSE(myCompleter.hasDotAt(5, 8));
}
TEST_F(CodeCompleter, DotToArrowCompletionForPointer)
{
auto myCompleter = setupCompleter(dotArrowCorrectionForPointerFileContainer);
......@@ -374,6 +396,14 @@ TEST_F(CodeCompleter, NoDotArrowCorrectionForOnlyDot)
ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection);
}
TEST_F(CodeCompleter, NoDotArrowCorrectionForColonColon)
{
auto myCompleter = setupCompleter(noDotArrowCorrectionForColonColonFileContainer);
const ClangBackEnd::CodeCompletions completions = myCompleter.complete(1, 7);
ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection);
}
ClangBackEnd::CodeCompleter CodeCompleter::setupCompleter(
const ClangBackEnd::FileContainer &fileContainer)
{
......
......@@ -150,4 +150,25 @@ TEST_F(UnsavedFile, Replace)
ASSERT_THAT(unsavedFile, IsUnsavedFile(filePath, expectedContent, expectedContent.byteSize()));
}
TEST_F(UnsavedFile, HasNoCharacterForTooBigOffset)
{
::UnsavedFile unsavedFile(filePath, fileContent);
ASSERT_FALSE(unsavedFile.hasCharacterAt(100, 'x'));
}
TEST_F(UnsavedFile, HasNoCharacterForWrongOffset)
{
::UnsavedFile unsavedFile(filePath, fileContent);
ASSERT_FALSE(unsavedFile.hasCharacterAt(0, 'x'));
}
TEST_F(UnsavedFile, HasCharacterForCorrectOffset)
{
::UnsavedFile unsavedFile(filePath, fileContent);
ASSERT_TRUE(unsavedFile.hasCharacterAt(0, 'c'));
}
} // anonymous namespace
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment