adding bang completion for template func, struct, class

This commit is contained in:
davu 2023-05-09 23:25:13 +02:00 committed by Jan Jurzitza
parent 0e85f165a9
commit 371a36e9d5
10 changed files with 83 additions and 9 deletions

View File

@ -45,6 +45,10 @@ TTree!(DSymbol*, SymbolsAllocator, true, "a < b") enumSymbols;
*/
TTree!(DSymbol*, SymbolsAllocator, true, "a < b") pointerSymbols;
/**
* Templated properties
*/
TTree!(DSymbol*, SymbolsAllocator, true, "a < b") templatedSymbols;
/**
* Variadic template parameters properties
*/

View File

@ -1041,6 +1041,7 @@ private:
continue;
SemanticSymbol* templateParameter = allocateSemanticSymbol(name,
kind, symbolFile, index);
symbol.acSymbol.qualifier = SymbolQualifier.templated;
if (type !is null)
addTypeToLookups(templateParameter.typeLookups, type);

View File

@ -203,6 +203,7 @@ do
case SymbolQualifier.array: lastSuffix.addChildren(arraySymbols[], false); break;
case SymbolQualifier.assocArray: lastSuffix.addChildren(assocArraySymbols[], false); break;
case SymbolQualifier.pointer: lastSuffix.addChildren(pointerSymbols[], false); break;
case SymbolQualifier.templated: lastSuffix.addChildren(templatedSymbols[], false); break;
}
if (suffix is null)

View File

@ -133,6 +133,8 @@ enum SymbolQualifier : ubyte
selectiveImport,
/// The symbol is a pointer
pointer,
/// The symbol is templated
templated,
}
/**

View File

@ -47,6 +47,11 @@ import dsymbol.utils;
import dcd.common.constants;
import dcd.common.messages;
enum CompletionToken {
none,
bracket, bang
}
/**
* Handles autocompletion
* Params:
@ -134,9 +139,13 @@ public AutocompleteResponse complete(const AutocompleteRequest request,
|| beforeTokens[$ - 1] == tok!",")
{
immutable size_t end = goBackToOpenParen(beforeTokens);
if (end != size_t.max)
return parenCompletion(beforeTokens[0 .. end], tokenArray,
if (end != size_t.max) {
return callTipCompletion(beforeTokens[0 .. end], tokenArray,
request.cursorPosition, moduleCache);
}
}
else if (beforeTokens[$ - 1] == tok!"!"){ // Bang completion
return callTipCompletion(beforeTokens, tokenArray, request.cursorPosition, moduleCache);
}
else
{
@ -218,7 +227,7 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, cursorPosition, moduleCache);
scope(exit) pair.destroy();
response.setCompletions(pair.scope_, getExpression(beforeTokens),
cursorPosition, CompletionType.identifiers, false, partial);
cursorPosition, CompletionType.identifiers, CompletionToken.none, partial);
if (!pair.ufcsSymbols.empty) {
response.completions ~= pair.ufcsSymbols.map!(s => makeSymbolCompletionInfo(s, CompletionKind.ufcsName)).array;
// Setting CompletionType in case of none symbols are found via setCompletions, but we have UFCS symbols.
@ -237,7 +246,7 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, 1, moduleCache);
scope(exit) pair.destroy();
response.setCompletions(pair.scope_, getExpression(beforeTokens),
1, CompletionType.identifiers, false, partial);
1, CompletionType.identifiers, CompletionToken.none, partial);
break;
default:
break;
@ -246,7 +255,7 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
}
/**
* Handles paren completion for function calls and some keywords
* Handles calltip completion for function calls and some keywords
* Params:
* beforeTokens = the tokens before the cursor
* tokenArray = all tokens in the file
@ -254,7 +263,7 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
* Returns:
* the autocompletion response
*/
AutocompleteResponse parenCompletion(T)(T beforeTokens,
AutocompleteResponse callTipCompletion(T)(T beforeTokens,
const(Token)[] tokenArray, size_t cursorPosition, ref ModuleCache moduleCache)
{
AutocompleteResponse response;
@ -309,7 +318,7 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens,
scope(exit) pair.destroy();
auto expression = getExpression(beforeTokens[0 .. $ - 1]);
response.setCompletions(pair.scope_, expression,
cursorPosition, CompletionType.calltips, beforeTokens[$ - 1] == tok!"[");
cursorPosition, CompletionType.calltips, getCompletionToken(beforeTokens));
if (!pair.ufcsSymbols.empty) {
response.completions ~= pair.ufcsSymbols.map!(s => makeSymbolCompletionInfo(s, CompletionKind.ufcsName)).array;
// Setting CompletionType in case of none symbols are found via setCompletions, but we have UFCS symbols.
@ -322,6 +331,18 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens,
return response;
}
CompletionToken getCompletionToken(T)(T beforeTokens) {
if(beforeTokens[$ - 1] == tok!"["){
return CompletionToken.bracket;
}
if(beforeTokens[$ - 1] == tok!"!"){
return CompletionToken.bang;
}
return CompletionToken.none;
}
/**
* Provides autocomplete for selective imports, e.g.:
* ---
@ -505,7 +526,7 @@ void setImportCompletions(T)(T tokens, ref AutocompleteResponse response,
*/
void setCompletions(T)(ref AutocompleteResponse response,
Scope* completionScope, T tokens, size_t cursorPosition,
CompletionType completionType, bool isBracket = false, string partial = null)
CompletionType completionType, CompletionToken completionToken = CompletionToken.none, string partial = null)
{
static void addSymToResponse(const(DSymbol)* s, ref AutocompleteResponse r, string p,
Scope* completionScope, size_t[] circularGuard = [])
@ -567,6 +588,11 @@ void setCompletions(T)(ref AutocompleteResponse response,
DSymbol*[] symbols = getSymbolsByTokenChain(completionScope, tokens,
cursorPosition, completionType);
// If bang completion we check if symbol is also templated
if (completionToken == CompletionToken.bang && symbols.length >= 1 && symbols[0].qualifier != SymbolQualifier.templated){
return;
}
if (symbols.length == 0)
return;
@ -607,7 +633,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
symbols = [dumb];
goto setCallTips;
}
if (isBracket)
if (completionToken == CompletionToken.bracket)
{
auto index = dumb.getPartsByName(internString("opIndex"));
if (index.length > 0)

View File

@ -0,0 +1,2 @@
calltips
this(T data)

View File

@ -0,0 +1,2 @@
calltips
this(T foo, X bar)

View File

@ -0,0 +1,2 @@
calltips
void doSomething(T)(T someElement)

View File

@ -0,0 +1,23 @@
struct Wrapper(T) {
T data;
}
class Something(T, X){
this(T foo, X bar){}
}
void doSomething(T)(T someElement){
}
void instantiateTemp1() {
Wrapper!
}
void instantiateTemp2() {
Something!
}
void instantiateTemp3() {
doSomething!
}

View File

@ -0,0 +1,11 @@
set -e
set -u
../../bin/dcd-client $1 file.d -c155 > actual.txt
diff actual.txt expected.txt --strip-trailing-cr
../../bin/dcd-client $1 file.d -c196 > actual2.txt
diff actual2.txt expected2.txt --strip-trailing-cr
../../bin/dcd-client $1 file.d -c239 > actual3.txt
diff actual3.txt expected3.txt --strip-trailing-cr