This commit is contained in:
ryuukk 2023-11-19 12:30:56 +00:00 committed by GitHub
commit 77a97dccc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 146 additions and 2 deletions

View File

@ -314,6 +314,19 @@ Otherwise the client outputs _00000_ so that the length of the answer is guarant
45 45
133 133
## Inlay Hints
Build a list of extra annoations for your IDE to display.
You must submit the content of the current file displayed in your editor.
dcd-client --inlayHints
This is a W.I.P., currently it only provide annoatations about aliases for your variables,
more is planned.
#### Example output
42 ->MyAlias->MyType
# Server # Server

View File

@ -78,10 +78,12 @@ enum RequestKind : ushort
localUse = 0b00000010_00000000, localUse = 0b00000010_00000000,
/// Remove import directory from server /// Remove import directory from server
removeImport = 0b00000100_00000000, removeImport = 0b00000100_00000000,
/// Get inlay hints
inlayHints = 0b00001000_00000000,
/// These request kinds require source code and won't be executed if there /// These request kinds require source code and won't be executed if there
/// is no source sent /// is no source sent
requiresSourceCode = autocomplete | doc | symbolLocation | search | localUse, requiresSourceCode = autocomplete | doc | symbolLocation | search | localUse | inlayHints,
// dfmt on // dfmt on
} }

View File

@ -62,6 +62,7 @@ int runClient(string[] args)
bool clearCache; bool clearCache;
bool symbolLocation; bool symbolLocation;
bool doc; bool doc;
bool inlayHints;
bool query; bool query;
bool printVersion; bool printVersion;
bool listImports; bool listImports;
@ -85,7 +86,7 @@ int runClient(string[] args)
getopt(args, "cursorPos|c", &cursorPos, "I", &addedImportPaths, getopt(args, "cursorPos|c", &cursorPos, "I", &addedImportPaths,
"R", &removedImportPaths, "port|p", &port, "help|h", &help, "R", &removedImportPaths, "port|p", &port, "help|h", &help,
"shutdown", &shutdown, "clearCache", &clearCache, "shutdown", &shutdown, "clearCache", &clearCache,
"symbolLocation|l", &symbolLocation, "doc|d", &doc, "symbolLocation|l", &symbolLocation, "doc|d", &doc, "inlayHints", &inlayHints,
"query|status|q", &query, "search|s", &search, "query|status|q", &query, "search|s", &search,
"version", &printVersion, "listImports", &listImports, "version", &printVersion, "listImports", &listImports,
"tcp", &useTCP, "socketFile", &socketFile, "tcp", &useTCP, "socketFile", &socketFile,
@ -234,6 +235,8 @@ int runClient(string[] args)
request.kind |= RequestKind.search; request.kind |= RequestKind.search;
else if(localUse) else if(localUse)
request.kind |= RequestKind.localUse; request.kind |= RequestKind.localUse;
else if (inlayHints)
request.kind |= RequestKind.inlayHints;
else else
request.kind |= RequestKind.autocomplete; request.kind |= RequestKind.autocomplete;
@ -255,6 +258,8 @@ int runClient(string[] args)
printSearchResponse(response); printSearchResponse(response);
else if (localUse) else if (localUse)
printLocalUse(response); printLocalUse(response);
else if (inlayHints)
printInlayHintsResponse(response);
else else
printCompletionResponse(response, fullOutput); printCompletionResponse(response, fullOutput);
@ -384,6 +389,17 @@ void printLocationResponse(ref const AutocompleteResponse response)
writeln(makeTabSeparated(response.symbolFilePath, response.symbolLocation.to!string)); writeln(makeTabSeparated(response.symbolFilePath, response.symbolLocation.to!string));
} }
void printInlayHintsResponse(ref const AutocompleteResponse response)
{
auto app = appender!(string[])();
foreach (ref completion; response.completions)
{
app.put(makeTabSeparated(completion.symbolLocation.to!string, completion.identifier));
}
foreach (line; app.data)
writeln(line);
}
void printCompletionResponse(ref const AutocompleteResponse response, bool extended) void printCompletionResponse(ref const AutocompleteResponse response, bool extended)
{ {
if (response.completions.length > 0) if (response.completions.length > 0)

View File

@ -0,0 +1,107 @@
/**
* This file is part of DCD, a development tool for the D programming language.
* Copyright (C) 2014 Brian Schott
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
module dcd.server.autocomplete.inlayhints;
import std.stdio;
import std.algorithm;
import std.array;
import std.experimental.allocator;
import std.experimental.logger;
import std.typecons;
import dcd.server.autocomplete.util;
import dparse.lexer;
import dparse.rollback_allocator;
import dsymbol.modulecache;
import dsymbol.symbol;
import dsymbol.scope_;
import dsymbol.conversion;
import dsymbol.string_interning;
import dcd.common.messages;
import containers.hashset;
public AutocompleteResponse getInlayHints(const AutocompleteRequest request,
ref ModuleCache moduleCache)
{
// trace("Getting inlay hints comments");
AutocompleteResponse response;
LexerConfig config;
config.fileName = "";
auto cache = StringCache(request.sourceCode.length.optimalBucketCount);
auto tokenArray = getTokensForParser(cast(ubyte[]) request.sourceCode, config, &cache);
RollbackAllocator rba;
auto pair = generateAutocompleteTrees(tokenArray, &rba, -1, moduleCache);
scope(exit) pair.destroy();
void check(DSymbol* it, ref HashSet!size_t visited)
{
if (visited.contains(cast(size_t) it))
return;
if (it.symbolFile != "stdin") return;
visited.insert(cast(size_t) it);
//writeln("sym: ", it.name," ", it.location, " kind: ", it.kind," qualifier: ", it.qualifier);
//if (auto type = it.type)
//{
// writeln(" ", type.name, " kind: ", type.kind, " qualifier", type.qualifier);
// if (auto ttype = type.type)
// writeln(" ", ttype.name, " kind: ", ttype.kind, " qualifier", ttype.qualifier);
//}
// aliases
// struct Data {}
// alias Alias1 = Data;
// Alias1 var; becomes: Alias1 [-> Data] var;
if (it.kind == CompletionKind.variableName && it.type && it.type.kind == CompletionKind.aliasName)
{
AutocompleteResponse.Completion c;
c.symbolLocation = it.location - 1;
DSymbol* type = it.type;
while (type)
{
if (type.kind == CompletionKind.aliasName && type.type)
c.identifier ~= "->" ~ type.type.name;
if (type.type && type.type.kind != CompletionKind.aliasName) break;
type = type.type;
}
response.completions ~= c;
}
foreach(part; it.opSlice())
check(part, visited);
}
HashSet!size_t visited;
foreach (symbol; pair.scope_.symbols)
{
check(symbol, visited);
foreach(part; symbol.opSlice())
check(part, visited);
}
return response;
}

View File

@ -24,3 +24,4 @@ import dcd.server.autocomplete.complete;
import dcd.server.autocomplete.doc; import dcd.server.autocomplete.doc;
import dcd.server.autocomplete.localuse; import dcd.server.autocomplete.localuse;
import dcd.server.autocomplete.symbols; import dcd.server.autocomplete.symbols;
import dcd.server.autocomplete.inlayhints;

View File

@ -347,6 +347,11 @@ int runServer(string[] args)
s.trySendResponse(symbolSearch(request, cache), "Could not perform symbol search"); s.trySendResponse(symbolSearch(request, cache), "Could not perform symbol search");
else if (request.kind & RequestKind.localUse) else if (request.kind & RequestKind.localUse)
s.trySendResponse(findLocalUse(request, cache), "Couldnot find local usage"); s.trySendResponse(findLocalUse(request, cache), "Couldnot find local usage");
else if (request.kind & RequestKind.inlayHints)
{
info("Getting inlay hints");
s.trySendResponse(getInlayHints(request, cache), "Could not get inlay hints");
}
else if (needResponse) else if (needResponse)
s.trySendResponse(AutocompleteResponse.ack, "Could not send ack"); s.trySendResponse(AutocompleteResponse.ack, "Could not send ack");
} }