forked from qt-creator/qt-creator
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: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Blah::
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user