Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert explicitely omitted ByRef arguments into temporary variables #1121

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions CodeConverter/CSharp/ExpressionNodeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1731,17 +1731,22 @@ async Task<ArgumentSyntax> ConvertArg(VBSyntax.ArgumentSyntax arg, int argIndex)
{
var argName = arg is VBSyntax.SimpleArgumentSyntax { IsNamed: true } namedArg ? namedArg.NameColonEquals.Name.Identifier.Text : null;
var parameterSymbol = invocationSymbol?.GetParameters().GetArgument(argName, argIndex);
var convertedArg = await ConvertArgForParameter(arg, parameterSymbol);

if (parameterSymbol != null) {
if (convertedArg is not null && parameterSymbol is not null) {
processedParameters.Add(parameterSymbol.Name);
}

return convertedArg;
}

async Task<ArgumentSyntax> ConvertArgForParameter(VBSyntax.ArgumentSyntax arg, IParameterSymbol parameterSymbol)
{
if (arg.IsOmitted) {
if (invocationSymbol != null && !invocationHasOverloads) {
forceNamedParameters = true;
return null; //Prefer to skip omitted and use named parameters when the symbol has only one overload
}

return ConvertOmittedArgument(parameterSymbol);
}

Expand Down
65 changes: 30 additions & 35 deletions Tests/CSharp/MemberTests/MemberTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4051,50 +4051,45 @@ public static int StaticTestProperty
}

[Fact]
public async Task TestMissingByRefArgumentWithNoExplicitDefaultValueAsync()
public async Task TestOmittedArgumentsAsync()
{
await TestConversionVisualBasicToCSharpAsync(
@"Imports System.Runtime.InteropServices
@"Class OmittedArguments
Sub M(Optional a As String = ""a"", ByRef Optional b As String = ""b"")
Dim s As String = """"

Class MissingByRefArgumentWithNoExplicitDefaultValue
Sub S()
ByRefNoDefault()
OptionalByRefNoDefault()
OptionalByRefWithDefault()
End Sub
M() 'omitted implicitly
M(,) 'omitted explicitly

M(s) 'omitted implicitly
M(s,) 'omitted explicitly

Private Sub ByRefNoDefault(ByRef str1 As String) : End Sub
Private Sub OptionalByRefNoDefault(<[Optional]> ByRef str2 As String) : End Sub
Private Sub OptionalByRefWithDefault(<[Optional], DefaultParameterValue(""a"")> ByRef str3 As String) : End Sub
M(a:=s) 'omitted implicitly
M(a:=s, ) 'omitted explicitly
End Sub
End Class", @"using System.Runtime.InteropServices;

internal partial class MissingByRefArgumentWithNoExplicitDefaultValue
internal partial class OmittedArguments
{
public void S()
public void M([Optional, DefaultParameterValue(""a"")] string a, [Optional, DefaultParameterValue(""b"")] ref string b)
{
ByRefNoDefault();
string argstr2 = default;
OptionalByRefNoDefault(str2: ref argstr2);
string argstr3 = ""a"";
OptionalByRefWithDefault(str3: ref argstr3);
}
string s = """";

private void ByRefNoDefault(ref string str1)
{
}
private void OptionalByRefNoDefault([Optional] ref string str2)
{
}
private void OptionalByRefWithDefault([Optional][DefaultParameterValue(""a"")] ref string str3)
{
string argb = ""b"";
M(b: ref argb); // omitted implicitly
string argb1 = ""b"";
M(b: ref argb1); // omitted explicitly

string argb2 = ""b"";
M(s, b: ref argb2); // omitted implicitly
string argb3 = ""b"";
M(s, b: ref argb3); // omitted explicitly

string argb4 = ""b"";
M(a: s, b: ref argb4); // omitted implicitly
string argb5 = ""b"";
M(a: s, b: ref argb5); // omitted explicitly
}
}
3 source compilation errors:
BC30455: Argument not specified for parameter 'str1' of 'Private Sub ByRefNoDefault(ByRef str1 As String)'.
BC30455: Argument not specified for parameter 'str2' of 'Private Sub OptionalByRefNoDefault(ByRef str2 As String)'.
BC30455: Argument not specified for parameter 'str3' of 'Private Sub OptionalByRefWithDefault(ByRef str3 As String)'.
1 target compilation errors:
CS7036: There is no argument given that corresponds to the required formal parameter 'str1' of 'MissingByRefArgumentWithNoExplicitDefaultValue.ByRefNoDefault(ref string)'
");
}");
}
}
Loading