diff --git a/src/dcd/server/autocomplete/complete.d b/src/dcd/server/autocomplete/complete.d index bb7f760..1f63427 100644 --- a/src/dcd/server/autocomplete/complete.d +++ b/src/dcd/server/autocomplete/complete.d @@ -136,17 +136,12 @@ public AutocompleteResponse complete(const AutocompleteRequest request, } } - auto calltipHint = getCalltipHint(beforeTokens); + size_t parenIndex; + auto calltipHint = getCalltipHint(beforeTokens, parenIndex); final switch (calltipHint) with (CalltipHint) { - case regularArguments: - immutable size_t end = goBackToOpenParen(beforeTokens); - if (end != size_t.max) - return calltipCompletion(beforeTokens[0 .. end], tokenArray, - request.cursorPosition, moduleCache, calltipHint); - break; - case templateArguments, indexOperator: - return calltipCompletion(beforeTokens, tokenArray, request.cursorPosition, moduleCache, calltipHint); + case regularArguments, templateArguments, indexOperator: + return calltipCompletion(beforeTokens[0 .. parenIndex], tokenArray, request.cursorPosition, moduleCache, calltipHint); case none: // could be import or dot completion if (beforeTokens.length < 2){ @@ -322,7 +317,7 @@ AutocompleteResponse calltipCompletion(T)(T beforeTokens, ScopeSymbolPair pair = generateAutocompleteTrees(tokenArray, &rba, cursorPosition, moduleCache); scope(exit) pair.destroy(); // We remove by 2 when the calltip hint is !( else remove by 1. - auto endOffset = beforeTokens.isBangParenCalltipHint ? 2 : 1; + auto endOffset = beforeTokens.isTemplateBangParen ? 2 : 1; auto expression = getExpression(beforeTokens[0 .. $ - endOffset]); response.setCompletions(pair.scope_, expression, cursorPosition, CompletionType.calltips, calltipHint); @@ -340,10 +335,8 @@ AutocompleteResponse calltipCompletion(T)(T beforeTokens, IdType getSignificantTokenId(T)(T beforeTokens){ auto significantTokenId = beforeTokens[$ - 2].type; - if (beforeTokens.isBangParenCalltipHint) { - if(beforeTokens[$ - 3] == tok!"identifier"){ - return beforeTokens[$ - 3].type; - } + if (beforeTokens.isTemplateBangParen) { + return beforeTokens[$ - 3].type; } return significantTokenId; } @@ -353,41 +346,37 @@ IdType getSignificantTokenId(T)(T beforeTokens){ * beforeTokens = tokens before the cursor * Returns: calltipHint based of beforeTokens */ -CalltipHint getCalltipHint(T)(T beforeTokens) { +CalltipHint getCalltipHint(T)(T beforeTokens, out size_t parenIndex) { if (beforeTokens.length < 2){ return CalltipHint.none; } - if (beforeTokens[$ - 1] == tok!"(" || beforeTokens[$ - 1] == tok!"[" - || beforeTokens[$ - 1] == tok!",") + + parenIndex = beforeTokens.length; + // evaluate at comma case + if (beforeTokens.isComma){ + parenIndex = beforeTokens.goBackToOpenParen; + // check if we are actually a "!(" + if (beforeTokens[0 .. parenIndex].isTemplateBangParen){ + return CalltipHint.templateArguments; + } + return CalltipHint.regularArguments; + } + + if (beforeTokens.isOpenParen || beforeTokens.isOpenSquareBracket) { return CalltipHint.regularArguments; } - if(beforeTokens[$ - 2] == tok!"identifier" && beforeTokens[$ - 1] == tok!"["){ + if(beforeTokens.isIndexOperator){ return CalltipHint.indexOperator; } - if(beforeTokens.isSingleBangCalltipHint || beforeTokens.isBangParenCalltipHint){ + if(beforeTokens.isTemplateBang || beforeTokens.isTemplateBangParen){ return CalltipHint.templateArguments; } return CalltipHint.none; } -// Check if we are doing a single "!" calltip hint -private bool isSingleBangCalltipHint(T)(T beforeTokens) { - return beforeTokens.length >= 2 - && beforeTokens[$ - 2] == tok!"identifier" - && beforeTokens[$ - 1] == tok!"!"; -} - -// Check if we are doing a "!(" calltip hint -private bool isBangParenCalltipHint(T)(T beforeTokens){ - return beforeTokens.length >= 3 - && beforeTokens[$ - 3] == tok!"identifier" - && beforeTokens[$ - 2] == tok!"!" - && beforeTokens[$ - 1] == tok!"("; -} - /** * Provides autocomplete for selective imports, e.g.: * --- diff --git a/src/dcd/server/autocomplete/util.d b/src/dcd/server/autocomplete/util.d index 6622af1..64d026f 100644 --- a/src/dcd/server/autocomplete/util.d +++ b/src/dcd/server/autocomplete/util.d @@ -546,8 +546,43 @@ AutocompleteResponse.Completion makeSymbolCompletionInfo(const DSymbol* symbol, return ret; } -bool doUFCSSearch(string beforeToken, string lastToken) +bool doUFCSSearch(string beforeToken, string lastToken) pure { // we do the search if they are different from eachother return beforeToken != lastToken; } + +// Check if we are doing an index operation calltip hint +bool isIndexOperator(T)(T beforeTokens) pure { + return beforeTokens.length >= 2 && beforeTokens[$ - 2] == tok!"identifier" && beforeTokens[$ - 1] == tok!"["; +} + +// Check if we are doing "," calltip hint +bool isComma(T)(T beforeTokens) pure { + return beforeTokens.length >= 1 && beforeTokens[$ - 1] == tok!","; +} + +// Check if we are doing "[" calltip hint +bool isOpenSquareBracket(T)(T beforeTokens) pure { + return beforeTokens.length >= 1 && beforeTokens[$ - 1] == tok!"["; +} + +// Check if we are doing "(" calltip hint +bool isOpenParen(T)(T beforeTokens) pure { + return beforeTokens.length >= 1 && beforeTokens[$ - 1] == tok!"("; +} + +// Check if we are doing a single "!" calltip hint +bool isTemplateBang(T)(T beforeTokens) pure { + return beforeTokens.length >= 2 + && beforeTokens[$ - 2] == tok!"identifier" + && beforeTokens[$ - 1] == tok!"!"; +} + +// Check if we are doing "!(" calltip hint +bool isTemplateBangParen(T)(T beforeTokens) pure { + return beforeTokens.length >= 3 + && beforeTokens[$ - 3] == tok!"identifier" + && beforeTokens[$ - 2] == tok!"!" + && beforeTokens[$ - 1] == tok!"("; +} diff --git a/tests/tc_template_bang_completion/expected6.txt b/tests/tc_template_bang_completion/expected6.txt new file mode 100644 index 0000000..bdd1b06 --- /dev/null +++ b/tests/tc_template_bang_completion/expected6.txt @@ -0,0 +1,2 @@ +calltips +Something(T, X) diff --git a/tests/tc_template_bang_completion/expected7.txt b/tests/tc_template_bang_completion/expected7.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/tc_template_bang_completion/expected8.txt b/tests/tc_template_bang_completion/expected8.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/tc_template_bang_completion/file.d b/tests/tc_template_bang_completion/file.d index 5b1423e..d9ba991 100644 --- a/tests/tc_template_bang_completion/file.d +++ b/tests/tc_template_bang_completion/file.d @@ -29,3 +29,15 @@ void instantiateTemp4() { void instantiateTemp5() { doSomething!("something", } + +void instantiateTemp6() { + Something!("something", +} + +void shouldNotComplete1() { + Something!! +} + +void shouldNotComplete2() { + Something!!( +} diff --git a/tests/tc_template_bang_completion/run.sh b/tests/tc_template_bang_completion/run.sh index 8f14b1c..54c8f88 100755 --- a/tests/tc_template_bang_completion/run.sh +++ b/tests/tc_template_bang_completion/run.sh @@ -15,3 +15,12 @@ diff actual4.txt expected4.txt --strip-trailing-cr ../../bin/dcd-client $1 file.d -c339 > actual5.txt diff actual5.txt expected5.txt --strip-trailing-cr + +../../bin/dcd-client $1 file.d -c393 > actual6.txt +diff actual6.txt expected6.txt --strip-trailing-cr + +../../bin/dcd-client $1 file.d -c437 > actual7.txt +diff actual7.txt expected7.txt --strip-trailing-cr + +../../bin/dcd-client $1 file.d -c482 > actual8.txt +diff actual8.txt expected8.txt --strip-trailing-cr