make sure templates from parts are also resolved

This commit is contained in:
ryuukk 2023-02-06 18:15:08 +01:00
parent 64db68fea5
commit 2b248747fa
3 changed files with 33 additions and 15 deletions

View File

@ -272,7 +272,7 @@ final class FirstPass : ASTVisitor
else if (typeIdentifierPart.identifierOrTemplateInstance.templateInstance.templateArguments.templateSingleArgument) else if (typeIdentifierPart.identifierOrTemplateInstance.templateInstance.templateArguments.templateSingleArgument)
{ {
auto singleArg = typeIdentifierPart.identifierOrTemplateInstance.templateInstance.templateArguments.templateSingleArgument; auto singleArg = typeIdentifierPart.identifierOrTemplateInstance.templateInstance.templateArguments.templateSingleArgument;
symbol.acSymbol.tmplArgNames.insert(istring(singleArg.token.text)); symbol.acSymbol.tmplArgNames ~= istring(singleArg.token.text);
} }
} }
} }

View File

@ -33,6 +33,7 @@ import std.experimental.allocator.gc_allocator : GCAllocator;
import std.experimental.logger; import std.experimental.logger;
import dparse.ast; import dparse.ast;
import dparse.lexer; import dparse.lexer;
import std.compiler;
void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache) void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache)
{ {
@ -55,13 +56,6 @@ void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCac
resolveType(currentSymbol.acSymbol, currentSymbol.typeLookups, resolveType(currentSymbol.acSymbol, currentSymbol.typeLookups,
moduleScope, cache); moduleScope, cache);
} }
if (currentSymbol.acSymbol.tmplArgNames.length > 0 && currentSymbol.acSymbol.type)
{
auto type = currentSymbol.acSymbol.type;
if (type.kind == structName || type.kind == className)
resolveTemplate(currentSymbol.acSymbol, type, moduleScope, cache);
}
break; break;
case importSymbol: case importSymbol:
if (currentSymbol.acSymbol.type is null) if (currentSymbol.acSymbol.type is null)
@ -101,6 +95,19 @@ void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCac
resolveMixinTemplates(currentSymbol.acSymbol, currentSymbol.typeLookups, resolveMixinTemplates(currentSymbol.acSymbol, currentSymbol.typeLookups,
moduleScope, cache); moduleScope, cache);
break; break;
case variableName:
if (currentSymbol.acSymbol.tmplArgNames.length > 0 && currentSymbol.acSymbol.type)
{
auto tArgNames = currentSymbol.acSymbol.tmplArgNames;
auto type = currentSymbol.acSymbol.type;
if (type.kind == structName || type.kind == className)
resolveTemplate(currentSymbol.acSymbol, type, tArgNames, moduleScope, cache);
}
else
{
warning("no type: ", currentSymbol.acSymbol.name," ", currentSymbol.acSymbol.kind);
}
break;
default: default:
break; break;
} }
@ -109,24 +116,30 @@ void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCac
/** /**
* Resolve template arguments * Resolve template arguments
*/ */
void resolveTemplate(DSymbol* sym, DSymbol* type, Scope* moduleScope, ref ModuleCache cache) void resolveTemplate(DSymbol* sym, DSymbol* type, scope const istring[] tmplArgNames, Scope* moduleScope, ref ModuleCache cache)
{ {
if (sym.tmplArgNames.length > 1) return; if (tmplArgNames.length > 1) return;
auto argName = sym.tmplArgNames.back; auto argName = tmplArgNames[0];
auto result = moduleScope.getSymbolsAtGlobalScope(argName); auto result = moduleScope.getSymbolsAtGlobalScope(argName);
if (result.length > 0) if (result.length > 0)
{ {
auto argSymbol = result[0]; auto argSymbol = result[0];
DSymbol* newType = GCAllocator.instance.make!DSymbol(type.name, type.kind, null); DSymbol* newType = GCAllocator.instance.make!DSymbol("", CompletionKind.dummy, null);
newType.name = type.name;
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.callTip = type.callTip;
DSymbol* currentT = null;
foreach(part; type.opSlice()) foreach(part; type.opSlice())
{ {
if (part.kind == CompletionKind.typeTmpParam) if (part.kind == CompletionKind.typeTmpParam)
{ } {
currentT = part;
}
else if (part.type && part.type.kind == CompletionKind.typeTmpParam) else if (part.type && part.type.kind == CompletionKind.typeTmpParam)
{ {
DSymbol* newPart = GCAllocator.instance.make!DSymbol(part.name, part.kind, argSymbol); DSymbol* newPart = GCAllocator.instance.make!DSymbol(part.name, part.kind, argSymbol);
@ -135,14 +148,19 @@ void resolveTemplate(DSymbol* sym, DSymbol* type, Scope* moduleScope, ref Module
newPart.symbolFile = part.symbolFile; newPart.symbolFile = part.symbolFile;
newPart.doc = part.doc; newPart.doc = part.doc;
newPart.callTip = part.callTip; newPart.callTip = part.callTip;
newPart.type = argSymbol;
newType.addChild(newPart, true); newType.addChild(newPart, true);
} }
else else
{ {
if (part.tmplArgNames.length > 0)
{
auto innerArg = part.tmplArgNames[0];
resolveTemplate(part, part.type, [argName], moduleScope, cache);
}
newType.addChild(part, false); newType.addChild(part, false);
} }
} }
sym.type = newType; sym.type = newType;
sym.ownType = true; sym.ownType = true;
} }

View File

@ -384,7 +384,7 @@ struct DSymbol
/** /**
* Names of template arguments * Names of template arguments
*/ */
UnrolledList!(istring) tmplArgNames; istring[] tmplArgNames;
/** /**
* Function parameter symbols * Function parameter symbols