From 516dff5f36f82056b65bb4bde11092a0e3ca79a5 Mon Sep 17 00:00:00 2001 From: ryuukk Date: Tue, 14 Feb 2023 04:20:24 +0100 Subject: [PATCH] save progress --- dsymbol/src/dsymbol/conversion/first.d | 50 ++++++++++++++++-------- dsymbol/src/dsymbol/conversion/second.d | 52 ++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 18 deletions(-) diff --git a/dsymbol/src/dsymbol/conversion/first.d b/dsymbol/src/dsymbol/conversion/first.d index 23f7cb2..2929082 100644 --- a/dsymbol/src/dsymbol/conversion/first.d +++ b/dsymbol/src/dsymbol/conversion/first.d @@ -353,13 +353,13 @@ final class FirstPass : ASTVisitor if (IdentifierOrTemplateInstance iot = ue.identifierOrTemplateInstance) { warning("has iot"); - - auto crumb = iot.identifier; - if (crumb != tok!"") - { - warning(": ", crumb.text); - lookup.breadcrumbs.insert(istring(crumb.text)); - } + buildChainTemplateOrIdentifier(symbol, lookup, ctx, iot); + //auto crumb = iot.identifier; + //if (crumb != tok!"") + //{ + // warning(": ", crumb.text); + // lookup.breadcrumbs.insert(istring(crumb.text)); + //} } if(ue.unaryExpression) traverseUnaryExpression(symbol, lookup, ctx, ue.unaryExpression); @@ -420,12 +420,26 @@ final class FirstPass : ASTVisitor currentScope.addSymbol(symbol.acSymbol, false); warning(" part: ", symbol.acSymbol.name); + scope(exit) warning("crumbs: ", symbol.typeLookups.front.breadcrumbs[]); + + if (currentSymbol.acSymbol.kind == CompletionKind.structName + || currentSymbol.acSymbol.kind == CompletionKind.unionName) + { + structFieldNames.insert(symbol.acSymbol.name); + // TODO: remove this cast. See the note on structFieldTypes + structFieldTypes.insert(null); + } + + // for auto declaration, we'll properly traverse the initializer // and set the proper crumbs instead of using just the first one // so we can handle things like cast/templates auto lookup = symbol.typeLookups.front; + istring[] copy; + foreach(crumb; lookup.breadcrumbs[]) + copy ~= crumb; lookup.breadcrumbs.clear(); auto initializer = part.initializer.nonVoidInitializer; @@ -479,13 +493,14 @@ final class FirstPass : ASTVisitor auto crumb = iot.identifier; if (crumb != tok!"") { - lookup.breadcrumbs.insert(istring(crumb.text)); + //lookup.breadcrumbs.insert(istring(crumb.text)); } else if (iot.templateInstance) { - auto tic = iot.templateInstance.identifier; - warning("template! ", tic.text); - lookup.breadcrumbs.insert(istring(tic.text)); + //auto tic = iot.templateInstance.identifier; + //warning("template! ", tic.text); + //if (tic != tok!"") + // lookup.breadcrumbs.insert(istring(tic.text)); lookup.ctx.root = GCAllocator.instance.make!(VariableContext.TypeInstance)(); processTemplateInstance(symbol, lookup, &lookup.ctx, lookup.ctx.root, iot.templateInstance); @@ -494,12 +509,15 @@ final class FirstPass : ASTVisitor } } - if (currentSymbol.acSymbol.kind == CompletionKind.structName - || currentSymbol.acSymbol.kind == CompletionKind.unionName) + if (symbol.acSymbol.name == "it") { - structFieldNames.insert(symbol.acSymbol.name); - // TODO: remove this cast. See the note on structFieldTypes - structFieldTypes.insert(null); + import core.stdc.stdlib: exit; + warning("crumb: ", lookup.breadcrumbs[]); + + warning("root: ", lookup.ctx.root.chain); + foreach(arg; lookup.ctx.root.args) + warning(" arg: ", arg.chain); + //exit(0); } } } diff --git a/dsymbol/src/dsymbol/conversion/second.d b/dsymbol/src/dsymbol/conversion/second.d index c2a8d85..2d9eb72 100644 --- a/dsymbol/src/dsymbol/conversion/second.d +++ b/dsymbol/src/dsymbol/conversion/second.d @@ -35,6 +35,8 @@ import std.experimental.logger; import dparse.ast; import dparse.lexer; +//package void warning(A...)(A args){} + void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache) { with (CompletionKind) final switch (currentSymbol.acSymbol.kind) @@ -63,7 +65,7 @@ void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCac if (lookup.ctx.root) { auto type = currentSymbol.acSymbol.type; - if (type.kind == structName || type.kind == className) + if (type.kind == structName || type.kind == className || (type.kind == functionName)) if (lookup.ctx.root.args.length > 0) { DSymbol*[string] mapping; @@ -120,6 +122,31 @@ void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCac } } + +string extractReturnType(string callTip) +{ + import std.string: indexOf; + + auto spaceIndex = callTip.indexOf(" "); + if (spaceIndex <= 0) return ""; + + auto retPart = callTip[0 .. spaceIndex]; + auto returnTypeConst = retPart.length > 6 ? retPart[0 .. 6] == "const(" : false; + auto returnTypeInout = retPart.length > 6 ? retPart[0 .. 6] == "inout(" : false; + if (returnTypeConst || returnTypeInout) + { + retPart = retPart[retPart.indexOf("(") + 1 .. $]; + retPart = retPart[0 .. retPart.indexOf(")")]; + } + auto returnTypePtr = retPart[$-1] == '*'; + auto returnTypeArr = retPart[$-1] == ']'; + if (returnTypePtr) + { + retPart = retPart[0 .. $-1]; + } + return retPart; +} + DSymbol* createTypeWithTemplateArgs(DSymbol* type, TypeLookup* lookup, VariableContext.TypeInstance* ti, ref ModuleCache cache, Scope* moduleScope, ref int depth, DSymbol*[string] m) { assert(type); @@ -209,11 +236,31 @@ DSymbol* createTypeWithTemplateArgs(DSymbol* type, TypeLookup* lookup, VariableC } + // 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 + // maybe it's time to properly handle it by creating a proper symbol, so we can have + // proper support for functions that return complex types such as templates + if (type.kind == CompletionKind.functionName) + { + auto callTip = type.callTip; + if (callTip.length > 1) + { + auto retType = extractReturnType(callTip); + if (retType in mapping) + { + newType.type = mapping[retType]; + } + } + } + assert(newType); - warning("process parts.."); + warning("process parts.. for type: ", type.name, ":", type.kind); + if (type.type) + warning (" >>>>>>".red, type.type.name); string[] T_names; foreach(part; type.opSlice()) { + warning("part: ", part.name, ":",part.kind, " t: ", part.type?part.type.name:""); if (part.kind == CompletionKind.typeTmpParam) { warning(" #", count, " ", part.name); @@ -244,6 +291,7 @@ DSymbol* createTypeWithTemplateArgs(DSymbol* type, TypeLookup* lookup, VariableC } else error(" mapping not found: ".red, part.type.name," type: ", type.name, " cur: ", ti.chain, "args: ", ti.args); + newType.addChild(newPart, true); } else