summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2016-01-28 18:43:14 +0100
committerNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2016-02-01 12:20:58 +0000
commit57877cc14de97eb5bf491c89e2c856e54859ed57 (patch)
tree0b6df9cfb0a2777689b676e486be94b4527e0aad
parentda27ea4d42864472f102943e89a0cd82f9ffe230 (diff)
downloadqt-creator-57877cc14de97eb5bf491c89e2c856e54859ed57.tar.gz
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>
-rw-r--r--src/tools/clangbackend/ipcsource/codecompleter.cpp10
-rw-r--r--src/tools/clangbackend/ipcsource/codecompleter.h3
-rw-r--r--src/tools/clangbackend/ipcsource/unsavedfile.cpp8
-rw-r--r--src/tools/clangbackend/ipcsource/unsavedfile.h1
-rw-r--r--tests/unit/unittest/codecompletiontest.cpp30
-rw-r--r--tests/unit/unittest/data/complete_withNoDotArrowCorrectionForColonColon.cpp1
-rw-r--r--tests/unit/unittest/unsavedfiletest.cpp21
7 files changed, 73 insertions, 1 deletions
diff --git a/src/tools/clangbackend/ipcsource/codecompleter.cpp b/src/tools/clangbackend/ipcsource/codecompleter.cpp
index a139e02edf..691686d047 100644
--- a/src/tools/clangbackend/ipcsource/codecompleter.cpp
+++ b/src/tools/clangbackend/ipcsource/codecompleter.cpp
@@ -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;
diff --git a/src/tools/clangbackend/ipcsource/codecompleter.h b/src/tools/clangbackend/ipcsource/codecompleter.h
index ceb594df63..99749414f4 100644
--- a/src/tools/clangbackend/ipcsource/codecompleter.h
+++ b/src/tools/clangbackend/ipcsource/codecompleter.h
@@ -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,
diff --git a/src/tools/clangbackend/ipcsource/unsavedfile.cpp b/src/tools/clangbackend/ipcsource/unsavedfile.cpp
index 1db76d22cf..b1c87e6025 100644
--- a/src/tools/clangbackend/ipcsource/unsavedfile.cpp
+++ b/src/tools/clangbackend/ipcsource/unsavedfile.cpp
@@ -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) {
diff --git a/src/tools/clangbackend/ipcsource/unsavedfile.h b/src/tools/clangbackend/ipcsource/unsavedfile.h
index fe738bb262..17e09667dc 100644
--- a/src/tools/clangbackend/ipcsource/unsavedfile.h
+++ b/src/tools/clangbackend/ipcsource/unsavedfile.h
@@ -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();
diff --git a/tests/unit/unittest/codecompletiontest.cpp b/tests/unit/unittest/codecompletiontest.cpp
index d7a6cba623..3b2eff7d82 100644
--- a/tests/unit/unittest/codecompletiontest.cpp
+++ b/tests/unit/unittest/codecompletiontest.cpp
@@ -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)
{
diff --git a/tests/unit/unittest/data/complete_withNoDotArrowCorrectionForColonColon.cpp b/tests/unit/unittest/data/complete_withNoDotArrowCorrectionForColonColon.cpp
new file mode 100644
index 0000000000..62af4343c1
--- /dev/null
+++ b/tests/unit/unittest/data/complete_withNoDotArrowCorrectionForColonColon.cpp
@@ -0,0 +1 @@
+Blah::
diff --git a/tests/unit/unittest/unsavedfiletest.cpp b/tests/unit/unittest/unsavedfiletest.cpp
index aa54550f2d..80f22ded35 100644
--- a/tests/unit/unittest/unsavedfiletest.cpp
+++ b/tests/unit/unittest/unsavedfiletest.cpp
@@ -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