From 5bbc3350342114f428feac0b20a0a68647c46973 Mon Sep 17 00:00:00 2001 From: davu Date: Sun, 26 Feb 2023 21:28:46 +0100 Subject: [PATCH] Adding return type name to symbol --- dsymbol/src/dsymbol/conversion/first.d | 10 +++-- dsymbol/src/dsymbol/conversion/second.d | 59 +++++++++++++++---------- dsymbol/src/dsymbol/symbol.d | 3 ++ dsymbol/src/dsymbol/tests.d | 21 +++++++++ dsymbol/src/dsymbol/type_lookup.d | 1 + 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/dsymbol/src/dsymbol/conversion/first.d b/dsymbol/src/dsymbol/conversion/first.d index e488566..080ade5 100644 --- a/dsymbol/src/dsymbol/conversion/first.d +++ b/dsymbol/src/dsymbol/conversion/first.d @@ -37,6 +37,7 @@ import std.experimental.allocator; import std.experimental.allocator.gc_allocator : GCAllocator; import std.experimental.logger; import std.typecons : Rebindable; +import std.array : appender; /** * First Pass handles the following: @@ -148,6 +149,11 @@ final class FirstPass : ASTVisitor processParameters(currentSymbol, dec.returnType, currentSymbol.acSymbol.name, dec.parameters, dec.templateParameters); } + auto app = appender!string(); + app.formatNode(dec.returnType); + + currentSymbol.typeLookups.insert(TypeLookupsAllocator.instance.make!TypeLookup( + istring(app.data), TypeLookupKind.returnType)); } override void visit(const FunctionLiteralExpression exp) @@ -778,7 +784,6 @@ private: void createConstructor() { - import std.array : appender; import std.range : zip; auto app = appender!string(); @@ -1064,7 +1069,6 @@ private: istring formatCallTip(const Type returnType, string name, const Parameters parameters, const TemplateParameters templateParameters) { - import std.array : appender; auto app = appender!string(); if (returnType !is null) @@ -1136,7 +1140,6 @@ private: lookup.breadcrumbs.insert(POINTER_SYMBOL_NAME); else if (suffix.delegateOrFunction != tok!"") { - import std.array : appender; auto app = appender!string(); formatNode(app, type); istring callTip = istring(app.data); @@ -1341,7 +1344,6 @@ void writeIotcTo(T)(const IdentifierOrTemplateChain iotc, ref T output) nothrow static istring convertChainToImportPath(const IdentifierChain ic) { import std.path : dirSeparator; - import std.array : appender; auto app = appender!string(); foreach (i, ident; ic.identifiers) { diff --git a/dsymbol/src/dsymbol/conversion/second.d b/dsymbol/src/dsymbol/conversion/second.d index 9142d16..3aacf89 100644 --- a/dsymbol/src/dsymbol/conversion/second.d +++ b/dsymbol/src/dsymbol/conversion/second.d @@ -33,6 +33,8 @@ import std.experimental.allocator.gc_allocator : GCAllocator; import std.experimental.logger; import dparse.ast; import dparse.lexer; +import std.algorithm : filter; +import std.range; void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache) { @@ -309,11 +311,28 @@ do private: +void resolveReturnType(DSymbol* symbol, ref TypeLookups typeLookups, + Scope* moduleScope, ref ModuleCache cache) +{ + foreach (returnType; typeLookups[].filter!(a => a.kind == TypeLookupKind.returnType)) + { + assert(returnType.breadcrumbs.length > 0); + auto parts = symbol.getPartsByName(returnType.breadcrumbs.front); + if (parts.empty){ + // If nothing found try to lookup within the global scope + auto found = moduleScope.getSymbolsAtGlobalScope(returnType.breadcrumbs.front); + if (!found.empty) { + symbol.returnType = found.front; + } + + } + } + +} + void resolveInheritance(DSymbol* symbol, ref TypeLookups typeLookups, Scope* moduleScope, ref ModuleCache cache) { - import std.algorithm : filter; - outer: foreach (TypeLookup* lookup; typeLookups[]) { if (lookup.kind != TypeLookupKind.inherit) @@ -355,9 +374,6 @@ void resolveInheritance(DSymbol* symbol, ref TypeLookups typeLookups, void resolveAliasThis(DSymbol* symbol, ref TypeLookups typeLookups, Scope* moduleScope, ref ModuleCache cache) { - import std.algorithm : filter; - import std.array : array; - foreach (aliasThis; typeLookups[].filter!(a => a.kind == TypeLookupKind.aliasThis)) { assert(aliasThis.breadcrumbs.length > 0); @@ -379,8 +395,6 @@ void resolveAliasThis(DSymbol* symbol, void resolveMixinTemplates(DSymbol* symbol, ref TypeLookups typeLookups, Scope* moduleScope, ref ModuleCache cache) { - import std.algorithm : filter; - foreach (mix; typeLookups[].filter!(a => a.kind == TypeLookupKind.mixinTemplate)) { assert(mix.breadcrumbs.length > 0); @@ -414,22 +428,21 @@ void resolveMixinTemplates(DSymbol* symbol, void resolveType(DSymbol* symbol, ref TypeLookups typeLookups, Scope* moduleScope, ref ModuleCache cache) { - - import std.conv; - - if (typeLookups.length == 0) - return; - assert(typeLookups.length == 1); - auto lookup = typeLookups.front; - if (lookup.kind == TypeLookupKind.varOrFunType) - resolveTypeFromType(symbol, lookup, moduleScope, cache, null); - else if (lookup.kind == TypeLookupKind.initializer) - resolveTypeFromInitializer(symbol, lookup, moduleScope, cache); - // issue 94 - else if (lookup.kind == TypeLookupKind.inherit) - resolveInheritance(symbol, typeLookups, moduleScope, cache); - else - assert(false, "How did this happen?"); + // going through the lookups + foreach(lookup; typeLookups) { + if (lookup.kind == TypeLookupKind.varOrFunType) + resolveTypeFromType(symbol, lookup, moduleScope, cache, null); + else if (lookup.kind == TypeLookupKind.initializer) + resolveTypeFromInitializer(symbol, lookup, moduleScope, cache); + // issue 94 + else if (lookup.kind == TypeLookupKind.inherit) + resolveInheritance(symbol, typeLookups, moduleScope, cache); + else if (lookup.kind == TypeLookupKind.returnType){ + resolveReturnType(symbol, typeLookups, moduleScope, cache); + } + else + assert(false, "How did this happen?"); + } } void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup, diff --git a/dsymbol/src/dsymbol/symbol.d b/dsymbol/src/dsymbol/symbol.d index d7203c4..5ca6c48 100644 --- a/dsymbol/src/dsymbol/symbol.d +++ b/dsymbol/src/dsymbol/symbol.d @@ -375,6 +375,9 @@ struct DSymbol // TODO: assert that the type is not a function DSymbol* type; + // Return type symbol, if symbol currently is of function kind + DSymbol* returnType; + // Is alias this symbols DSymbol*[] aliasThisSymbols; /** diff --git a/dsymbol/src/dsymbol/tests.d b/dsymbol/src/dsymbol/tests.d index 3652388..3a0bae5 100644 --- a/dsymbol/src/dsymbol/tests.d +++ b/dsymbol/src/dsymbol/tests.d @@ -126,6 +126,27 @@ unittest } } +unittest +{ + ModuleCache cache; + writeln("Get return type name"); + auto source = q{ int meaningOfLife() { return 42; } }; + auto pair = generateAutocompleteTrees(source, cache); + auto meaningOfLife = pair.symbol.getFirstPartNamed(istring("meaningOfLife")); + assert(meaningOfLife.returnType.name == "int"); +} + +unittest +{ + ModuleCache cache; + writeln("Get return type name from class method"); + auto source = q{ class Life { uint meaningOfLife() { return 42; } }}; + auto pair = generateAutocompleteTrees(source, cache); + auto lifeClass = pair.symbol.getFirstPartNamed(istring("Life")); + auto meaningOfLife = lifeClass.getFirstPartNamed(istring("meaningOfLife")); + assert(meaningOfLife.returnType.name == "uint"); +} + unittest { ModuleCache cache; diff --git a/dsymbol/src/dsymbol/type_lookup.d b/dsymbol/src/dsymbol/type_lookup.d index 2260e57..84e14db 100644 --- a/dsymbol/src/dsymbol/type_lookup.d +++ b/dsymbol/src/dsymbol/type_lookup.d @@ -14,6 +14,7 @@ enum TypeLookupKind : ubyte mixinTemplate, varOrFunType, selectiveImport, + returnType, } /**