From 7a52c92139bc72c2b67a254d5c995e48c4b5f160 Mon Sep 17 00:00:00 2001 From: ryuukk Date: Wed, 1 Feb 2023 18:52:40 +0100 Subject: [PATCH] Add a 3rd phase to tesolve missing types that were parsed recursively --- dsymbol/src/dsymbol/conversion/package.d | 69 ++++++++++++++++++++++++ dsymbol/src/dsymbol/conversion/second.d | 4 ++ 2 files changed, 73 insertions(+) diff --git a/dsymbol/src/dsymbol/conversion/package.d b/dsymbol/src/dsymbol/conversion/package.d index 0cd5919..8477ed3 100644 --- a/dsymbol/src/dsymbol/conversion/package.d +++ b/dsymbol/src/dsymbol/conversion/package.d @@ -32,6 +32,7 @@ import dsymbol.string_interning; import dsymbol.symbol; import std.algorithm; import std.experimental.allocator; +import containers.hashset; /** * Used by autocompletion. @@ -47,6 +48,74 @@ ScopeSymbolPair generateAutocompleteTrees(const(Token)[] tokens, first.run(); secondPass(first.rootSymbol, first.moduleScope, cache); + + void tryResolve(Scope* sc, ref ModuleCache cache) + { + auto symbols = sc.symbols; + foreach (item; symbols) + { + DSymbol* target = item.type; + + void resolvePart(DSymbol* part, Scope* sc, ref HashSet!size_t visited) + { + if (visited.contains(cast(size_t) part)) + return; + visited.insert(cast(size_t) part); + + // no type but a callTip, let's resolve its type + if (part.type is null && part.callTip !is null) + { + auto typeName = part.callTip; + + // check if it is available in the scope + // otherwise grab its module symbol to check if it's publickly available + auto result = sc.getSymbolsAtGlobalScope(typeName); + if (result.length > 0) + { + part.type = result[0]; + return; + } + else + { + auto moduleSymbol = cache.getModuleSymbol(part.symbolFile); + auto first = moduleSymbol.getFirstPartNamed(typeName); + if (first !is null) + { + part.type = first; + return; + } + else + { + // type couldn't be found, that's stuff like templates + // now we could try to resolve them! + // warning("can't resolve: ", part.name, " callTip: ", typeName); + return; + } + } + } + + if (part.type !is null) + { + foreach (typePart; part.type.opSlice()) + resolvePart(typePart, sc, visited); + } + } + + if (target !is null) + { + HashSet!size_t visited; + foreach (part; target.opSlice()) + { + resolvePart(part, sc, visited); + } + } + } + if (sc.parent !is null) tryResolve(sc.parent, cache); + } + + auto desired = first.moduleScope.getScopeByCursor(cursorPosition); + tryResolve(desired, cache); + auto r = move(first.rootSymbol.acSymbol); typeid(SemanticSymbol).destroy(first.rootSymbol); return ScopeSymbolPair(r, move(first.moduleScope)); diff --git a/dsymbol/src/dsymbol/conversion/second.d b/dsymbol/src/dsymbol/conversion/second.d index 933bfef..c0082e2 100644 --- a/dsymbol/src/dsymbol/conversion/second.d +++ b/dsymbol/src/dsymbol/conversion/second.d @@ -245,7 +245,11 @@ do if (symbols.length > 0) currentSymbol = symbols[0]; else + { + // store the callTip, that'll be useful to resolve the type later + symbol.callTip = istring(part); return; + } } } else