From 434a838d20eae3f3d7860dd5b620e2a76a3c2c28 Mon Sep 17 00:00:00 2001 From: davu Date: Sat, 25 Feb 2023 19:05:40 +0100 Subject: [PATCH] Updated for PR --- dsymbol/src/dsymbol/conversion/second.d | 28 +++++++++---------- dsymbol/src/dsymbol/symbol.d | 4 +-- src/dcd/server/autocomplete/ufcs.d | 26 +++++++++++------ .../expected_aliased_struct_test.txt | 1 + .../fooutils/fooutils.d | 1 + 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/dsymbol/src/dsymbol/conversion/second.d b/dsymbol/src/dsymbol/conversion/second.d index d6874af..9142d16 100644 --- a/dsymbol/src/dsymbol/conversion/second.d +++ b/dsymbol/src/dsymbol/conversion/second.d @@ -146,7 +146,8 @@ do { if (moduleSymbol is null) { - DeferredSymbol* deferred = DeferredSymbolsAllocator.instance.make!DeferredSymbol(acSymbol); + DeferredSymbol* deferred = DeferredSymbolsAllocator.instance.make!DeferredSymbol( + acSymbol); cache.deferredSymbols.insert(deferred); } else @@ -188,8 +189,8 @@ do } if (!isArr && !isAssoc && !isFunction) break; - immutable qualifier = isAssoc ? SymbolQualifier.assocArray : - (isFunction ? SymbolQualifier.func : SymbolQualifier.array); + immutable qualifier = isAssoc ? SymbolQualifier.assocArray + : (isFunction ? SymbolQualifier.func : SymbolQualifier.array); lastSuffix = GCAllocator.instance.make!DSymbol(back, CompletionKind.dummy, lastSuffix); lastSuffix.qualifier = qualifier; lastSuffix.ownType = true; @@ -282,7 +283,7 @@ do symbol.ownType = true; if (currentSymbol is null && !remainingImports.empty) { -// info("Deferring type resolution for ", symbol.name); + // info("Deferring type resolution for ", symbol.name); auto deferred = DeferredSymbolsAllocator.instance.make!DeferredSymbol(suffix); // TODO: The scope has ownership of the import information deferred.imports.insert(remainingImports[]); @@ -298,7 +299,7 @@ do else if (!remainingImports.empty) { auto deferred = DeferredSymbolsAllocator.instance.make!DeferredSymbol(symbol); -// info("Deferring type resolution for ", symbol.name); + // info("Deferring type resolution for ", symbol.name); // TODO: The scope has ownership of the import information deferred.imports.insert(remainingImports[]); deferred.typeLookups.insert(lookup); @@ -355,6 +356,7 @@ 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)) { @@ -363,7 +365,7 @@ void resolveAliasThis(DSymbol* symbol, if (parts.length == 0 || parts[0].type is null) continue; - symbol.aliasThisSymbol = parts[0]; + symbol.aliasThisSymbols ~= parts; DSymbol* s = GCAllocator.instance.make!DSymbol(IMPORT_SYMBOL_NAME, CompletionKind.importSymbol, parts[0].type); @@ -430,7 +432,6 @@ void resolveType(DSymbol* symbol, ref TypeLookups typeLookups, assert(false, "How did this happen?"); } - void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup, Scope* moduleScope, ref ModuleCache cache) { @@ -450,8 +451,7 @@ void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup, if (currentSymbol is null) return; } - else - if (crumb == ARRAY_LITERAL_SYMBOL_NAME) + else if (crumb == ARRAY_LITERAL_SYMBOL_NAME) { auto arr = GCAllocator.instance.make!(DSymbol)(ARRAY_LITERAL_SYMBOL_NAME, CompletionKind.dummy, currentSymbol); arr.qualifier = SymbolQualifier.array; @@ -465,8 +465,8 @@ void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup, // Index expressions can be an array index or an AA index if (currentSymbol.qualifier == SymbolQualifier.array - || currentSymbol.qualifier == SymbolQualifier.assocArray - || currentSymbol.kind == CompletionKind.aliasName) + || currentSymbol.qualifier == SymbolQualifier.assocArray + || currentSymbol.kind == CompletionKind.aliasName) { if (currentSymbol.type !is null) currentSymbol = currentSymbol.type; @@ -488,7 +488,7 @@ void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup, if (currentSymbol is null) return; if (currentSymbol.qualifier == SymbolQualifier.array - || currentSymbol.qualifier == SymbolQualifier.assocArray) + || currentSymbol.qualifier == SymbolQualifier.assocArray) { currentSymbol = currentSymbol.type; break; @@ -509,7 +509,7 @@ void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup, else { typeSwap(currentSymbol); - if (currentSymbol is null ) + if (currentSymbol is null) return; currentSymbol = currentSymbol.getFirstPartNamed(crumb); } @@ -525,7 +525,7 @@ void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup, void typeSwap(ref DSymbol* currentSymbol) { while (currentSymbol !is null && currentSymbol.type !is currentSymbol - && (currentSymbol.kind == CompletionKind.variableName + && (currentSymbol.kind == CompletionKind.variableName || currentSymbol.kind == CompletionKind.importSymbol || currentSymbol.kind == CompletionKind.withSymbol || currentSymbol.kind == CompletionKind.aliasName)) diff --git a/dsymbol/src/dsymbol/symbol.d b/dsymbol/src/dsymbol/symbol.d index 03b75a0..d7203c4 100644 --- a/dsymbol/src/dsymbol/symbol.d +++ b/dsymbol/src/dsymbol/symbol.d @@ -375,8 +375,8 @@ struct DSymbol // TODO: assert that the type is not a function DSymbol* type; - // Is using alias this - DSymbol* aliasThisSymbol; + // Is alias this symbols + DSymbol*[] aliasThisSymbols; /** * Names of function arguments */ diff --git a/src/dcd/server/autocomplete/ufcs.d b/src/dcd/server/autocomplete/ufcs.d index 77372e4..904c627 100644 --- a/src/dcd/server/autocomplete/ufcs.d +++ b/src/dcd/server/autocomplete/ufcs.d @@ -129,12 +129,17 @@ bool willImplicitBeUpcasted(string from, string to) return INTEGER_PROMOTIONS[from] == to; } -bool matchAliasThis(const(DSymbol)* aliasThisSymbol, const(DSymbol)* incomingSymbol) +bool matchAliasThis(const(DSymbol)* beforeDotType, const(DSymbol)* incomingSymbol) { - if(aliasThisSymbol) { - return isCallableWithArg(incomingSymbol, aliasThisSymbol.type); + // For now we are only resolving the first alias this symbol + // when multiple alias this are supported, we can rethink another solution + if (!beforeDotType.aliasThisSymbols + || !beforeDotType.aliasThisSymbols.front + || beforeDotType.aliasThisSymbols.front == beforeDotType) + { + return false; } - return false; + return isCallableWithArg(incomingSymbol, beforeDotType.aliasThisSymbols.front.type); } /** @@ -157,9 +162,10 @@ bool isCallableWithArg(const(DSymbol)* incomingSymbol, const(DSymbol)* beforeDot if (incomingSymbol.kind == CompletionKind.functionName && !incomingSymbol .functionParameters.empty) { - return beforeDotType is incomingSymbol.functionParameters.front.type - || willImplicitBeUpcasted(beforeDotType.name, incomingSymbol.functionParameters.front.type.name) - || matchAliasThis(beforeDotType.aliasThisSymbol, incomingSymbol); + return beforeDotType is incomingSymbol.functionParameters.front.type + || willImplicitBeUpcasted(beforeDotType.name, incomingSymbol + .functionParameters.front.type.name) + || matchAliasThis(beforeDotType, incomingSymbol); } @@ -208,12 +214,14 @@ bool doUFCSSearch(string beforeToken, string lastToken) void getUFCSParenCompletion(ref DSymbol*[] symbols, Scope* completionScope, istring firstToken, istring nextToken, size_t cursorPosition) { - DSymbol* firstSymbol = completionScope.getFirstSymbolByNameAndCursor(firstToken, cursorPosition); + DSymbol* firstSymbol = completionScope.getFirstSymbolByNameAndCursor( + firstToken, cursorPosition); if (firstSymbol is null) return; - DSymbol*[] possibleUFCSSymbol = completionScope.getSymbolsByNameAndCursor(nextToken, cursorPosition); + DSymbol*[] possibleUFCSSymbol = completionScope.getSymbolsByNameAndCursor( + nextToken, cursorPosition); foreach (nextSymbol; possibleUFCSSymbol) { if (nextSymbol && nextSymbol.functionParameters) diff --git a/tests/tc_ufcs_struct_completion/expected_aliased_struct_test.txt b/tests/tc_ufcs_struct_completion/expected_aliased_struct_test.txt index 28bb143..585a654 100644 --- a/tests/tc_ufcs_struct_completion/expected_aliased_struct_test.txt +++ b/tests/tc_ufcs_struct_completion/expected_aliased_struct_test.txt @@ -7,6 +7,7 @@ min k sizeof k stringof k tupleof k +ufcsExactAliasedType F ufcsSomeInt F ufcsSomeShort F x v diff --git a/tests/tc_ufcs_struct_completion/fooutils/fooutils.d b/tests/tc_ufcs_struct_completion/fooutils/fooutils.d index 99810ce..cbd0299 100644 --- a/tests/tc_ufcs_struct_completion/fooutils/fooutils.d +++ b/tests/tc_ufcs_struct_completion/fooutils/fooutils.d @@ -20,4 +20,5 @@ void ufcsBarScope(ref scope Foo foo, string mama) {} void ufcsBarReturnScope(return scope Foo foo, string mama) {} void ufcsSomeInt(int x) {} void ufcsSomeShort(short x) {} +void ufcsExactAliasedType(IntAliased x) {} private void ufcsBarPrivate(Foo foo, string message) {} \ No newline at end of file