Display template parameters for the code completion

This commit is contained in:
ryuukk 2023-10-05 05:26:35 +02:00
parent 5d1cfb6db2
commit 1be5d16f5e
3 changed files with 41 additions and 6 deletions

View File

@ -250,10 +250,16 @@ final class FirstPass : ASTVisitor
void processTypeIdentifierPart(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, VariableContext.TypeInstance* current, TypeIdentifierPart tip) void processTypeIdentifierPart(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, VariableContext.TypeInstance* current, TypeIdentifierPart tip)
{ {
if (tip.identifierOrTemplateInstance) if (tip.identifierOrTemplateInstance)
{
processIdentifierOrTemplate(symbol, lookup, ctx, current, tip.identifierOrTemplateInstance); processIdentifierOrTemplate(symbol, lookup, ctx, current, tip.identifierOrTemplateInstance);
if (current)
current.calltip = buildCalltip(tip.identifierOrTemplateInstance.tokens);
}
if (tip.typeIdentifierPart) if (tip.typeIdentifierPart)
{
processTypeIdentifierPart(symbol, lookup, ctx, current, tip.typeIdentifierPart); processTypeIdentifierPart(symbol, lookup, ctx, current, tip.typeIdentifierPart);
}
// TODO: handle `tip.dot` and `tip.indexer` // TODO: handle `tip.dot` and `tip.indexer`
} }
@ -348,6 +354,31 @@ final class FirstPass : ASTVisitor
} }
} }
string buildCalltip(const(Token)[] tokens)
{
string calltip;
foreach(tk; tokens)
{
if (tk == tok!"!")
calltip ~= "!";
else if (tk == tok!"(")
calltip ~= "(";
else if (tk == tok!")")
calltip ~= ")";
else if (tk == tok!"[")
calltip ~= "[";
else if (tk == tok!"]")
calltip ~= "]";
else if (tk == tok!",")
calltip ~= ",";
else if (tk == tok!"")
calltip ~= " ";
else
calltip ~= tk.text;
}
return calltip;
}
void traverseUnaryExpression(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, UnaryExpression ue) void traverseUnaryExpression(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, UnaryExpression ue)
{ {
if (PrimaryExpression pe = ue.primaryExpression) if (PrimaryExpression pe = ue.primaryExpression)
@ -449,8 +480,11 @@ final class FirstPass : ASTVisitor
if (dec.type && dec.type.type2 && dec.type.type2.typeIdentifierPart) if (dec.type && dec.type.type2 && dec.type.type2.typeIdentifierPart)
{ {
TypeIdentifierPart typeIdentifierPart = cast(TypeIdentifierPart) dec.type.type2.typeIdentifierPart; TypeIdentifierPart typeIdentifierPart = cast(TypeIdentifierPart) dec.type.type2.typeIdentifierPart;
lookup.ctx.root = GCAllocator.instance.make!(VariableContext.TypeInstance)(); lookup.ctx.root = GCAllocator.instance.make!(VariableContext.TypeInstance)();
if (typeIdentifierPart.identifierOrTemplateInstance)
lookup.ctx.calltip = buildCalltip(typeIdentifierPart.identifierOrTemplateInstance.tokens);
processTypeIdentifierPart(symbol, lookup, &lookup.ctx, lookup.ctx.root, typeIdentifierPart); processTypeIdentifierPart(symbol, lookup, &lookup.ctx, lookup.ctx.root, typeIdentifierPart);
} }
} }

View File

@ -35,6 +35,7 @@ import dparse.ast;
import dparse.lexer; import dparse.lexer;
import std.algorithm : filter; import std.algorithm : filter;
import std.range; import std.range;
import std.stdio;
void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache) void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache)
{ {
@ -165,13 +166,12 @@ DSymbol* createTypeWithTemplateArgs(DSymbol* type, TypeLookup* lookup, VariableC
{ {
assert(type); assert(type);
DSymbol* newType = GCAllocator.instance.make!DSymbol("dummy", CompletionKind.dummy, null); DSymbol* newType = GCAllocator.instance.make!DSymbol("dummy", CompletionKind.dummy, null);
newType.name = type.name; newType.name = ti ? istring(ti.calltip) : istring(lookup.ctx.calltip);
newType.kind = type.kind; newType.kind = type.kind;
newType.qualifier = type.qualifier; newType.qualifier = type.qualifier;
newType.protection = type.protection; newType.protection = type.protection;
newType.symbolFile = type.symbolFile; newType.symbolFile = type.symbolFile;
newType.doc = type.doc; newType.doc = type.doc;
newType.callTip = type.callTip;
newType.type = type.type; newType.type = type.type;
DSymbol*[string] mapping; DSymbol*[string] mapping;
@ -189,7 +189,6 @@ DSymbol* createTypeWithTemplateArgs(DSymbol* type, TypeLookup* lookup, VariableC
continue; continue;
} }
auto key = part.name; auto key = part.name;
DSymbol* first; DSymbol* first;
bool isBuiltin; bool isBuiltin;
foreach(i, crumb; ti.args[count].chain) foreach(i, crumb; ti.args[count].chain)
@ -234,7 +233,6 @@ DSymbol* createTypeWithTemplateArgs(DSymbol* type, TypeLookup* lookup, VariableC
} }
} }
// HACK: to support functions with template arguments that return a generic type // HACK: to support functions with template arguments that return a generic type
// first.d in processParameters only store the function's return type in the callTip // first.d in processParameters only store the function's return type in the callTip
// maybe it's time to properly handle it by creating a proper symbol, so we can have // maybe it's time to properly handle it by creating a proper symbol, so we can have
@ -334,7 +332,7 @@ void resolveTemplate(DSymbol* variableSym, DSymbol* type, TypeLookup* lookup, Va
if (current.chain.length == 0) return; // TODO: should not be empty, happens for simple stuff Inner inner; if (current.chain.length == 0) return; // TODO: should not be empty, happens for simple stuff Inner inner;
DSymbol* newType = createTypeWithTemplateArgs(type, lookup, current, cache, moduleScope, depth, mapping); DSymbol* newType = createTypeWithTemplateArgs(type, lookup, current, cache, moduleScope, depth, mapping);
//writeln(">>", variableSym.name, " > ", newType.name);
variableSym.type = newType; variableSym.type = newType;
variableSym.ownType = true; variableSym.ownType = true;
} }
@ -524,6 +522,7 @@ do
suffix.ownType = false; suffix.ownType = false;
symbol.type = lastSuffix; symbol.type = lastSuffix;
symbol.ownType = true; symbol.ownType = true;
if (currentSymbol is null && !remainingImports.empty) if (currentSymbol is null && !remainingImports.empty)
{ {
// info("Deferring type resolution for ", symbol.name); // info("Deferring type resolution for ", symbol.name);

View File

@ -48,6 +48,8 @@ struct VariableContext
string[] chain; string[] chain;
TypeInstance*[] args; TypeInstance*[] args;
string name; string name;
string calltip;
} }
TypeInstance* root; TypeInstance* root;
string calltip;
} }