diff --git a/dsymbol/src/dsymbol/conversion/second.d b/dsymbol/src/dsymbol/conversion/second.d index 433cd66..d6874af 100644 --- a/dsymbol/src/dsymbol/conversion/second.d +++ b/dsymbol/src/dsymbol/conversion/second.d @@ -362,6 +362,9 @@ void resolveAliasThis(DSymbol* symbol, auto parts = symbol.getPartsByName(aliasThis.breadcrumbs.front); if (parts.length == 0 || parts[0].type is null) continue; + + symbol.aliasThisSymbol = parts[0]; + DSymbol* s = GCAllocator.instance.make!DSymbol(IMPORT_SYMBOL_NAME, CompletionKind.importSymbol, parts[0].type); symbol.addChild(s, true); diff --git a/dsymbol/src/dsymbol/symbol.d b/dsymbol/src/dsymbol/symbol.d index f6d2abb..03b75a0 100644 --- a/dsymbol/src/dsymbol/symbol.d +++ b/dsymbol/src/dsymbol/symbol.d @@ -375,6 +375,8 @@ struct DSymbol // TODO: assert that the type is not a function DSymbol* type; + // Is using alias this + DSymbol* aliasThisSymbol; /** * Names of function arguments */ diff --git a/src/dcd/server/autocomplete/ufcs.d b/src/dcd/server/autocomplete/ufcs.d index 2d1f386..77372e4 100644 --- a/src/dcd/server/autocomplete/ufcs.d +++ b/src/dcd/server/autocomplete/ufcs.d @@ -13,7 +13,6 @@ import std.string; import dparse.lexer : tok; import std.regex; import containers.hashset : HashSet; -import dparse.ast; // https://dlang.org/spec/type.html#implicit-conversions enum string[string] INTEGER_PROMOTIONS = [ @@ -121,8 +120,6 @@ DSymbol*[] getSymbolsForUFCS(Scope* completionScope, const(DSymbol)* beforeDotSy bool willImplicitBeUpcasted(string from, string to) { - import std.stdio; - string* found = from in INTEGER_PROMOTIONS; if (!found) { @@ -132,6 +129,14 @@ bool willImplicitBeUpcasted(string from, string to) return INTEGER_PROMOTIONS[from] == to; } +bool matchAliasThis(const(DSymbol)* aliasThisSymbol, const(DSymbol)* incomingSymbol) +{ + if(aliasThisSymbol) { + return isCallableWithArg(incomingSymbol, aliasThisSymbol.type); + } + return false; +} + /** * Params: * incomingSymbol = the function symbol to check if it is valid for UFCS with `beforeDotType`. @@ -152,8 +157,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); + return beforeDotType is incomingSymbol.functionParameters.front.type + || willImplicitBeUpcasted(beforeDotType.name, incomingSymbol.functionParameters.front.type.name) + || matchAliasThis(beforeDotType.aliasThisSymbol, incomingSymbol); + } return false; diff --git a/tests/tc_ufcs_struct_completion/expected_aliased_struct_test.txt b/tests/tc_ufcs_struct_completion/expected_aliased_struct_test.txt new file mode 100644 index 0000000..28bb143 --- /dev/null +++ b/tests/tc_ufcs_struct_completion/expected_aliased_struct_test.txt @@ -0,0 +1,12 @@ +identifiers +alignof k +init k +mangleof k +max k +min k +sizeof k +stringof k +tupleof k +ufcsSomeInt F +ufcsSomeShort F +x v diff --git a/tests/tc_ufcs_struct_completion/expected.txt b/tests/tc_ufcs_struct_completion/expected_struct_test.txt similarity index 100% rename from tests/tc_ufcs_struct_completion/expected.txt rename to tests/tc_ufcs_struct_completion/expected_struct_test.txt diff --git a/tests/tc_ufcs_struct_completion/fooutils/fooutils.d b/tests/tc_ufcs_struct_completion/fooutils/fooutils.d index 334c19c..99810ce 100644 --- a/tests/tc_ufcs_struct_completion/fooutils/fooutils.d +++ b/tests/tc_ufcs_struct_completion/fooutils/fooutils.d @@ -5,7 +5,7 @@ struct Foo { } struct IntAliased { - int x; + short x; alias x this; } @@ -19,4 +19,5 @@ void ufcsBarRefImmuttableWrapped(ref immutable(Foo) foo, string mama) {} void ufcsBarScope(ref scope Foo foo, string mama) {} void ufcsBarReturnScope(return scope Foo foo, string mama) {} void ufcsSomeInt(int x) {} +void ufcsSomeShort(short x) {} private void ufcsBarPrivate(Foo foo, string message) {} \ No newline at end of file