module scope op, add support for partial string and allow after `,[(`

This commit is contained in:
Basile Burg 2018-12-22 13:45:51 +01:00
parent b600aaa07a
commit 94538b398d
12 changed files with 42 additions and 18 deletions

View File

@ -68,11 +68,14 @@ public AutocompleteResponse complete(const AutocompleteRequest request,
fakeIdent.type = tok!"identifier"; 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` // 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 // 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`). // because within a module semantic is the same (`myModule.stuff` -> `.stuff`).
if (tokenArray.length >= 3 && tokenArray[0] == tok!"module" && if (tokenArray.length >= 3 && tokenArray[0] == tok!"module" && beforeTokens.length &&
beforeTokens[$-1] == tok!".") (beforeTokens[$-1] == tok!"." || dotId))
{ {
const upper = tokenArray.countUntil!(a => a.type == tok!";"); const upper = tokenArray.countUntil!(a => a.type == tok!";");
bool isSame = true; bool isSame = true;
@ -80,11 +83,12 @@ public AutocompleteResponse complete(const AutocompleteRequest request,
if (upper != -1 && beforeTokens.length >= upper * 2) if (upper != -1 && beforeTokens.length >= upper * 2)
foreach (immutable i; 0 .. upper) 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 // verify that the chain is well located after an expr or a decl
if (i == 0) if (i == 0)
{ {
if (beforeTokens[j].type.among(tok!"{", tok!"}", tok!";")) if (beforeTokens[j].type.among(tok!"{", tok!"}", tok!";", tok!"[",
tok!"(", tok!",", tok!":"))
continue; continue;
} }
// compare the end of the "before tokens" (access chain) // 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 // 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) 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) if (beforeTokens.length >= 2)
@ -200,21 +210,21 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
response.setCompletions(pair.scope_, getExpression(beforeTokens), response.setCompletions(pair.scope_, getExpression(beforeTokens),
cursorPosition, CompletionType.identifiers, false, partial); cursorPosition, CompletionType.identifiers, false, partial);
break; break;
// these tokens before a "." mean "Module Scope Operator"
case tok!":":
case tok!"(": 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!";":
case tok!"}": case tok!"}":
case tok!",":
auto allocator = scoped!(ASTAllocator)(); auto allocator = scoped!(ASTAllocator)();
RollbackAllocator rba; RollbackAllocator rba;
ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator, ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, allocator,
&rba, 1, moduleCache); &rba, 1, moduleCache);
scope(exit) pair.destroy(); scope(exit) pair.destroy();
response.setCompletions(pair.scope_, getExpression(beforeTokens), response.setCompletions(pair.scope_, getExpression(beforeTokens),
1, CompletionType.identifiers, false, "stdin"); 1, CompletionType.identifiers, false, partial);
break; break;
default: default:
break; break;
@ -520,7 +530,9 @@ void setCompletions(T)(ref AutocompleteResponse response,
foreach (s; currentSymbols.filter!(a => isPublicCompletionKind(a.kind) foreach (s; currentSymbols.filter!(a => isPublicCompletionKind(a.kind)
&& a.kind != CompletionKind.importSymbol && a.kind != CompletionKind.importSymbol
&& a.kind != CompletionKind.dummy && 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); response.completions ~= makeSymbolCompletionInfo(s, s.kind);
} }

View File

@ -0,0 +1,3 @@
identifiers
var1 v
var2 v

View File

@ -0,0 +1 @@
module m; int var1, var2; auto a = [m.var1,m.v ];

View File

@ -1,5 +1,7 @@
set -e set -e
set -u set -u
../../bin/dcd-client $1 file.d -c82 > actual.txt ../../bin/dcd-client $1 file1.d -c82 > actual1.txt
diff actual.txt expected.txt diff actual1.txt expected1.txt
../../bin/dcd-client $1 file2.d -c46 > actual2.txt
diff actual2.txt expected2.txt

View File

@ -1,5 +0,0 @@
set -e
set -u
../../bin/dcd-client $1 file.d -c59 > actual.txt
diff actual.txt expected.txt

View File

@ -0,0 +1,3 @@
identifiers
var1 v
var2 v

View File

@ -0,0 +1 @@
module m; int var1, var2; auto a = [.var1,.v ];

View File

@ -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