Skip to content

Commit b88c2aa

Browse files
Split out, simplify and neaten the output
1 parent 6caedbf commit b88c2aa

File tree

2 files changed

+31
-26
lines changed

2 files changed

+31
-26
lines changed

CodeConverter/CSharp/ExpressionNodeVisitor.cs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -408,44 +408,49 @@ public override async Task<CSharpSyntaxNode> VisitSimpleArgument(VBasic.Syntax.S
408408
var symbol = GetInvocationSymbol(invocation);
409409
SyntaxToken token = default(SyntaxToken);
410410
var convertedArgExpression = ((ExpressionSyntax)await node.Expression.AcceptAsync(TriviaConvertingExpressionVisitor)).SkipParens();
411+
var typeConversionAnalyzer = CommonConversions.TypeConversionAnalyzer;
411412
if (symbol is IMethodSymbol methodSymbol) {
412413
var parameters = (CommonConversions.GetCsOriginalSymbolOrNull(methodSymbol.OriginalDefinition) ?? methodSymbol).GetParameters();
413414
var refType = GetRefConversionType(node, argList, parameters, out var argName, out var refKind);
414-
415+
token = GetRefToken(refKind);
415416
if (refType != RefConversion.Inline) {
416-
string prefix = $"arg{argName}";
417-
var refLhs = convertedArgExpression;
418-
var expressionTypeInfo = _semanticModel.GetTypeInfo(node.Expression);
419-
bool useVar = expressionTypeInfo.Type?.Equals(expressionTypeInfo.ConvertedType) == true && !CommonConversions.ShouldPreferExplicitType(node.Expression, expressionTypeInfo.ConvertedType, out var _);
420-
var typeSyntax = CommonConversions.GetTypeSyntax(expressionTypeInfo.ConvertedType, useVar);
421-
422-
if (convertedArgExpression is ElementAccessExpressionSyntax eae) {
423-
//Hoist out the container so we can assign back to the same one after (like VB does)
424-
var tmpContainer = _additionalLocals.Hoist(new AdditionalDeclaration("tmp", eae.Expression, ValidSyntaxFactory.VarType));
425-
convertedArgExpression = eae.WithExpression(tmpContainer.IdentifierName);
426-
}
427-
428-
convertedArgExpression = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(node.Expression, convertedArgExpression, defaultToCast: refKind != RefKind.None);
429-
430-
var local = _additionalLocals.Hoist(new AdditionalDeclaration(prefix, convertedArgExpression, typeSyntax));
431-
convertedArgExpression = local.IdentifierName;
432-
433-
if (refType == RefConversion.PreAndPostAssignment) {
434-
var convertedLocalIdentifier = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(node.Expression, local.IdentifierName, forceSourceType: expressionTypeInfo.ConvertedType, forceTargetType: expressionTypeInfo.Type);
435-
_additionalLocals.Hoist(new AdditionalAssignment(refLhs, convertedLocalIdentifier));
436-
}
417+
convertedArgExpression = HoistByRefDeclaration(node, convertedArgExpression, refType, argName, refKind);
437418
} else {
438-
convertedArgExpression = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(node.Expression, convertedArgExpression, defaultToCast: refKind != RefKind.None);
419+
convertedArgExpression = typeConversionAnalyzer.AddExplicitConversion(node.Expression, convertedArgExpression, defaultToCast: refKind != RefKind.None);
439420
}
440-
token = GetRefToken(refKind);
441421
} else {
442-
convertedArgExpression = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(node.Expression, convertedArgExpression);
422+
convertedArgExpression = typeConversionAnalyzer.AddExplicitConversion(node.Expression, convertedArgExpression);
443423
}
444424

445425
var nameColon = node.IsNamed ? SyntaxFactory.NameColon((IdentifierNameSyntax)await node.NameColonEquals.Name.AcceptAsync(TriviaConvertingExpressionVisitor)) : null;
446426
return SyntaxFactory.Argument(nameColon, token, convertedArgExpression);
447427
}
448428

429+
private ExpressionSyntax HoistByRefDeclaration(VBSyntax.SimpleArgumentSyntax node, ExpressionSyntax refLValue, RefConversion refType, string argName, RefKind refKind)
430+
{
431+
string prefix = $"arg{argName}";
432+
var expressionTypeInfo = _semanticModel.GetTypeInfo(node.Expression);
433+
bool useVar = expressionTypeInfo.Type?.Equals(expressionTypeInfo.ConvertedType) == true && !CommonConversions.ShouldPreferExplicitType(node.Expression, expressionTypeInfo.ConvertedType, out var _);
434+
var typeSyntax = CommonConversions.GetTypeSyntax(expressionTypeInfo.ConvertedType, useVar);
435+
436+
if (refLValue is ElementAccessExpressionSyntax eae) {
437+
//Hoist out the container so we can assign back to the same one after (like VB does)
438+
var tmpContainer = _additionalLocals.Hoist(new AdditionalDeclaration("tmp", eae.Expression, ValidSyntaxFactory.VarType));
439+
refLValue = eae.WithExpression(tmpContainer.IdentifierName);
440+
}
441+
442+
var withCast = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(node.Expression, refLValue, defaultToCast: refKind != RefKind.None);
443+
444+
var local = _additionalLocals.Hoist(new AdditionalDeclaration(prefix, withCast, typeSyntax));
445+
446+
if (refType == RefConversion.PreAndPostAssignment) {
447+
var convertedLocalIdentifier = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(node.Expression, local.IdentifierName, forceSourceType: expressionTypeInfo.ConvertedType, forceTargetType: expressionTypeInfo.Type);
448+
_additionalLocals.Hoist(new AdditionalAssignment(refLValue, convertedLocalIdentifier));
449+
}
450+
451+
return local.IdentifierName;
452+
}
453+
449454
private static SyntaxToken GetRefToken(RefKind refKind)
450455
{
451456
SyntaxToken token;

Tests/CSharp/ExpressionTests/ByRefTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ public void Main()
506506
tmp[1] = argstr;
507507
Debug.Assert((Other.lst[1] ?? """") == (4.ToString() ?? """"));
508508
var tmp1 = Other.lst2;
509-
string argstr1 = Conversions.ToString(Other.lst2[1]);
509+
string argstr1 = Conversions.ToString(tmp1[1]);
510510
DoSomething(ref argstr1);
511511
tmp1[1] = argstr1;
512512
Debug.Assert(Conversions.ToBoolean(Operators.ConditionalCompareObjectEqual(Other.lst2[1], 5.ToString(), false)));

0 commit comments

Comments
 (0)