From 670c05bf370a631d21641ce1c436142c132100ca Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Sat, 29 Dec 2018 16:40:24 +0100 Subject: [PATCH] fix #558 - regression in import completion due to FQN autocomplete --- src/dcd/server/autocomplete/complete.d | 42 ++++++++++++++++---------- tests/tc_issue558/expected.txt | 3 ++ tests/tc_issue558/file.d | 1 + tests/tc_issue558/run.sh | 5 +++ 4 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 tests/tc_issue558/expected.txt create mode 100644 tests/tc_issue558/file.d create mode 100755 tests/tc_issue558/run.sh diff --git a/src/dcd/server/autocomplete/complete.d b/src/dcd/server/autocomplete/complete.d index 192361f..1992ded 100644 --- a/src/dcd/server/autocomplete/complete.d +++ b/src/dcd/server/autocomplete/complete.d @@ -77,35 +77,45 @@ public AutocompleteResponse complete(const AutocompleteRequest request, if (tokenArray.length >= 3 && tokenArray[0] == tok!"module" && beforeTokens.length && (beforeTokens[$-1] == tok!"." || dotId)) { - const upper = tokenArray.countUntil!(a => a.type == tok!";" && - a.index < beforeTokens[$-1].index); - bool isSame = upper != -1; + const moduleDeclEndIndex = tokenArray.countUntil!(a => a.type == tok!";"); + bool beginsWithModuleName; // enough room for the module decl and the fqn... - if (isSame && beforeTokens.length >= upper * 2) - foreach (immutable i; 0 .. upper) + if (moduleDeclEndIndex != -1 && beforeTokens.length >= moduleDeclEndIndex * 2) + foreach (immutable i; 0 .. moduleDeclEndIndex) { - const j = beforeTokens.length - upper + i - 1 - ubyte(dotId); + const expectIdt = bool(i & 1); + const expectDot = !expectIdt; + const j = beforeTokens.length - moduleDeclEndIndex + i - 1 - ubyte(dotId); + // verify that the chain is well located after an expr or a decl if (i == 0) { - if (beforeTokens[j].type.among(tok!"{", tok!"}", tok!";", tok!"[", - tok!"(", tok!",", tok!":")) - continue; + if (!beforeTokens[j].type.among(tok!"{", tok!"}", tok!";", + tok!"[", tok!"(", tok!",", tok!":")) + break; } - // compare the end of the "before tokens" (access chain) + // then compare the end of the "before tokens" (access chain) // with the firsts (ModuleDeclaration) - else if ((tokenArray[i].type == tok!"." && beforeTokens[j].type == tok!".") || - (tokenArray[i].type == tok!"identifier" && tokenArray[i].text == beforeTokens[j].text)) + else { - continue; + // even index : must be a dot + if (expectDot && + (tokenArray[i].type != tok!"." || beforeTokens[j].type != tok!".")) + break; + // odd index : identifiers must match + else if (expectIdt && + (tokenArray[i].type != tok!"identifier" || beforeTokens[j].type != tok!"identifier" || + tokenArray[i].text != beforeTokens[j].text)) + break; } - isSame = false; - break; + if (i == moduleDeclEndIndex - 1) + beginsWithModuleName = true; } + // replace the "before tokens" with a pattern making the remaining // parts of the completion process think that it's a "Module Scope Operator". - if (isSame) + if (beginsWithModuleName) { if (dotId) beforeTokens = assumeSorted([const Token(tok!"{"), const Token(tok!"."), diff --git a/tests/tc_issue558/expected.txt b/tests/tc_issue558/expected.txt new file mode 100644 index 0000000..0bb4300 --- /dev/null +++ b/tests/tc_issue558/expected.txt @@ -0,0 +1,3 @@ +identifiers +bar M +module1 M diff --git a/tests/tc_issue558/file.d b/tests/tc_issue558/file.d new file mode 100644 index 0000000..3f3de7f --- /dev/null +++ b/tests/tc_issue558/file.d @@ -0,0 +1 @@ +module foo.foo.test; import package1.; int x; void y() {} diff --git a/tests/tc_issue558/run.sh b/tests/tc_issue558/run.sh new file mode 100755 index 0000000..d27dfa5 --- /dev/null +++ b/tests/tc_issue558/run.sh @@ -0,0 +1,5 @@ +set -e +set -u + +../../bin/dcd-client $1 file.d -c37 > actual.txt +diff actual.txt expected.txt