From 94538b398df668abbc6d35f3e01939f89a674735 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Sat, 22 Dec 2018 13:45:51 +0100 Subject: [PATCH] module scope op, add support for partial string and allow after `,[(` --- src/dcd/server/autocomplete/complete.d | 34 +++++++++++++------ .../{expected.txt => expected1.txt} | 0 tests/tc_currmod_fqn/expected2.txt | 3 ++ tests/tc_currmod_fqn/{file.d => file1.d} | 0 tests/tc_currmod_fqn/file2.d | 1 + tests/tc_currmod_fqn/run.sh | 6 ++-- tests/tc_global_dot/run.sh | 5 --- .../expected1.txt} | 0 tests/tc_module_scope_op/expected2.txt | 3 ++ .../file.d => tc_module_scope_op/file1.d} | 0 tests/tc_module_scope_op/file2.d | 1 + tests/tc_module_scope_op/run.sh | 7 ++++ 12 files changed, 42 insertions(+), 18 deletions(-) rename tests/tc_currmod_fqn/{expected.txt => expected1.txt} (100%) create mode 100644 tests/tc_currmod_fqn/expected2.txt rename tests/tc_currmod_fqn/{file.d => file1.d} (100%) create mode 100644 tests/tc_currmod_fqn/file2.d delete mode 100755 tests/tc_global_dot/run.sh rename tests/{tc_global_dot/expected.txt => tc_module_scope_op/expected1.txt} (100%) create mode 100644 tests/tc_module_scope_op/expected2.txt rename tests/{tc_global_dot/file.d => tc_module_scope_op/file1.d} (100%) create mode 100644 tests/tc_module_scope_op/file2.d create mode 100755 tests/tc_module_scope_op/run.sh diff --git a/src/dcd/server/autocomplete/complete.d b/src/dcd/server/autocomplete/complete.d index f82143d..0399f86 100644 --- a/src/dcd/server/autocomplete/complete.d +++ b/src/dcd/server/autocomplete/complete.d @@ -68,11 +68,14 @@ public AutocompleteResponse complete(const AutocompleteRequest request, fakeIdent.type = tok!"identifier"; } + const bool dotId = beforeTokens.length >= 2 && + beforeTokens[$-1] == tok!"identifier" && beforeTokens[$-2] == tok!"."; + // detects if the completion request uses the current module `ModuleDeclaration` // as access chain. In this case removes this access chain, and just keep the dot // because within a module semantic is the same (`myModule.stuff` -> `.stuff`). - if (tokenArray.length >= 3 && tokenArray[0] == tok!"module" && - beforeTokens[$-1] == tok!".") + if (tokenArray.length >= 3 && tokenArray[0] == tok!"module" && beforeTokens.length && + (beforeTokens[$-1] == tok!"." || dotId)) { const upper = tokenArray.countUntil!(a => a.type == tok!";"); bool isSame = true; @@ -80,11 +83,12 @@ public AutocompleteResponse complete(const AutocompleteRequest request, if (upper != -1 && beforeTokens.length >= upper * 2) foreach (immutable i; 0 .. upper) { - const j = beforeTokens.length - upper + i - 1; + const j = beforeTokens.length - upper + 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!";")) + if (beforeTokens[j].type.among(tok!"{", tok!"}", tok!";", tok!"[", + tok!"(", tok!",", tok!":")) continue; } // compare the end of the "before tokens" (access chain) @@ -99,9 +103,15 @@ public AutocompleteResponse complete(const AutocompleteRequest request, } // replace the "before tokens" with a pattern making the remaining - // part of the completions think that it's a "Module Scope Operator". + // parts of the completion process think that it's a "Module Scope Operator". if (isSame) - beforeTokens = assumeSorted([const Token(tok!"{"), const Token(tok!".")]); + { + if (dotId) + beforeTokens = assumeSorted([const Token(tok!"{"), const Token(tok!"."), + cast(const) beforeTokens[$-1]]); + else + beforeTokens = assumeSorted([const Token(tok!"{"), const Token(tok!".")]); + } } if (beforeTokens.length >= 2) @@ -200,21 +210,21 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray, response.setCompletions(pair.scope_, getExpression(beforeTokens), cursorPosition, CompletionType.identifiers, false, partial); break; + // these tokens before a "." mean "Module Scope Operator" + case tok!":": case tok!"(": case tok!"[": - case tok!":": - break; - // these tokens before a "." means "Module Scope Operator" case tok!"{": case tok!";": case tok!"}": + case tok!",": auto allocator = scoped!(ASTAllocator)(); RollbackAllocator rba; ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator, &rba, 1, moduleCache); scope(exit) pair.destroy(); response.setCompletions(pair.scope_, getExpression(beforeTokens), - 1, CompletionType.identifiers, false, "stdin"); + 1, CompletionType.identifiers, false, partial); break; default: break; @@ -520,7 +530,9 @@ void setCompletions(T)(ref AutocompleteResponse response, foreach (s; currentSymbols.filter!(a => isPublicCompletionKind(a.kind) && a.kind != CompletionKind.importSymbol && a.kind != CompletionKind.dummy - && a.symbolFile == partial)) + && a.symbolFile == "stdin" + && (partial !is null && toUpper(a.name.data).startsWith(toUpper(partial)) + || partial is null))) { response.completions ~= makeSymbolCompletionInfo(s, s.kind); } diff --git a/tests/tc_currmod_fqn/expected.txt b/tests/tc_currmod_fqn/expected1.txt similarity index 100% rename from tests/tc_currmod_fqn/expected.txt rename to tests/tc_currmod_fqn/expected1.txt diff --git a/tests/tc_currmod_fqn/expected2.txt b/tests/tc_currmod_fqn/expected2.txt new file mode 100644 index 0000000..dd1f1e6 --- /dev/null +++ b/tests/tc_currmod_fqn/expected2.txt @@ -0,0 +1,3 @@ +identifiers +var1 v +var2 v diff --git a/tests/tc_currmod_fqn/file.d b/tests/tc_currmod_fqn/file1.d similarity index 100% rename from tests/tc_currmod_fqn/file.d rename to tests/tc_currmod_fqn/file1.d diff --git a/tests/tc_currmod_fqn/file2.d b/tests/tc_currmod_fqn/file2.d new file mode 100644 index 0000000..ede1640 --- /dev/null +++ b/tests/tc_currmod_fqn/file2.d @@ -0,0 +1 @@ +module m; int var1, var2; auto a = [m.var1,m.v ]; diff --git a/tests/tc_currmod_fqn/run.sh b/tests/tc_currmod_fqn/run.sh index 3101783..7e121c8 100755 --- a/tests/tc_currmod_fqn/run.sh +++ b/tests/tc_currmod_fqn/run.sh @@ -1,5 +1,7 @@ set -e set -u -../../bin/dcd-client $1 file.d -c82 > actual.txt -diff actual.txt expected.txt +../../bin/dcd-client $1 file1.d -c82 > actual1.txt +diff actual1.txt expected1.txt +../../bin/dcd-client $1 file2.d -c46 > actual2.txt +diff actual2.txt expected2.txt diff --git a/tests/tc_global_dot/run.sh b/tests/tc_global_dot/run.sh deleted file mode 100755 index 9236ef9..0000000 --- a/tests/tc_global_dot/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -set -e -set -u - -../../bin/dcd-client $1 file.d -c59 > actual.txt -diff actual.txt expected.txt diff --git a/tests/tc_global_dot/expected.txt b/tests/tc_module_scope_op/expected1.txt similarity index 100% rename from tests/tc_global_dot/expected.txt rename to tests/tc_module_scope_op/expected1.txt diff --git a/tests/tc_module_scope_op/expected2.txt b/tests/tc_module_scope_op/expected2.txt new file mode 100644 index 0000000..dd1f1e6 --- /dev/null +++ b/tests/tc_module_scope_op/expected2.txt @@ -0,0 +1,3 @@ +identifiers +var1 v +var2 v diff --git a/tests/tc_global_dot/file.d b/tests/tc_module_scope_op/file1.d similarity index 100% rename from tests/tc_global_dot/file.d rename to tests/tc_module_scope_op/file1.d diff --git a/tests/tc_module_scope_op/file2.d b/tests/tc_module_scope_op/file2.d new file mode 100644 index 0000000..4742de8 --- /dev/null +++ b/tests/tc_module_scope_op/file2.d @@ -0,0 +1 @@ +module m; int var1, var2; auto a = [.var1,.v ]; diff --git a/tests/tc_module_scope_op/run.sh b/tests/tc_module_scope_op/run.sh new file mode 100755 index 0000000..34731f1 --- /dev/null +++ b/tests/tc_module_scope_op/run.sh @@ -0,0 +1,7 @@ +set -e +set -u + +../../bin/dcd-client $1 file1.d -c59 > actual1.txt +diff actual1.txt expected1.txt +../../bin/dcd-client $1 file2.d -c44 > actual2.txt +diff actual2.txt expected2.txt