@@ -211,9 +211,22 @@ public override async Task<SyntaxList<StatementSyntax>> VisitAssignmentStatement
211211 var lhs = await node . Left . AcceptAsync < ExpressionSyntax > ( _expressionVisitor ) ;
212212 var lOperation = _semanticModel . GetOperation ( node . Left ) ;
213213
214- //Already dealt with by call to the same method in ConvertInvocationExpression
215214 var ( parameterizedPropertyAccessMethod , _) = await CommonConversions . GetParameterizedPropertyAccessMethodAsync ( lOperation ) ;
216- if ( parameterizedPropertyAccessMethod != null ) return SingleStatement ( lhs ) ;
215+
216+ // If it's a simple assignment, we can return early as it's already handled by ConvertInvocationExpression
217+ if ( parameterizedPropertyAccessMethod != null && node . IsKind ( VBasic . SyntaxKind . SimpleAssignmentStatement ) ) {
218+ return SingleStatement ( lhs ) ;
219+ }
220+
221+ // For compound assignments, we want to expand it to the setter, but parameterizedPropertyAccessMethod above
222+ // returned 'get_Item' or 'set_Item' depending on operation context.
223+ // We know for sure the left-hand side is a getter invocation for compound assignments (e.g. this.get_Item(0) += 2),
224+ // but we need the setter name to build the final expression.
225+ string setMethodName = null ;
226+ if ( lOperation is IPropertyReferenceOperation pro && pro . Arguments . Any ( ) && ! Microsoft . CodeAnalysis . VisualBasic . VisualBasicExtensions . IsDefault ( pro . Property ) ) {
227+ setMethodName = pro . Property . SetMethod ? . Name ;
228+ }
229+
217230 var rhs = await node . Right . AcceptAsync < ExpressionSyntax > ( _expressionVisitor ) ;
218231
219232 if ( node . Left is VBSyntax . IdentifierNameSyntax id &&
@@ -241,16 +254,41 @@ _methodNode is VBSyntax.MethodBlockSyntax mb &&
241254
242255 var nonCompoundRhs = SyntaxFactory . BinaryExpression ( nonCompound , lhs , typeConvertedRhs ) ;
243256 var typeConvertedNonCompoundRhs = CommonConversions . TypeConversionAnalyzer . AddExplicitConversion ( node . Right , nonCompoundRhs , forceSourceType : rhsTypeInfo . ConvertedType , forceTargetType : lhsTypeInfo . Type ) ;
244- if ( nonCompoundRhs != typeConvertedNonCompoundRhs ) {
257+ if ( nonCompoundRhs != typeConvertedNonCompoundRhs || setMethodName != null ) {
245258 kind = SyntaxKind . SimpleAssignmentExpression ;
246259 typeConvertedRhs = typeConvertedNonCompoundRhs ;
247260 }
261+ } else if ( setMethodName != null && node . IsKind ( VBasic . SyntaxKind . ExponentiateAssignmentStatement ) ) {
262+ // ExponentiateAssignmentStatement evaluates to Math.Pow invocation which might need casting back to lhsType
263+ var typeConvertedNonCompoundRhs = CommonConversions . TypeConversionAnalyzer . AddExplicitConversion ( node . Right , typeConvertedRhs , forceSourceType : _semanticModel . Compilation . GetTypeByMetadataName ( "System.Double" ) , forceTargetType : lhsTypeInfo . Type ) ;
264+ kind = SyntaxKind . SimpleAssignmentExpression ;
265+ typeConvertedRhs = typeConvertedNonCompoundRhs ;
248266 }
249267
250268 rhs = typeConvertedRhs ;
251-
252- var assignment = SyntaxFactory . AssignmentExpression ( kind , lhs , rhs ) ;
253269
270+ if ( setMethodName != null ) {
271+ if ( lhs is InvocationExpressionSyntax ies ) {
272+ ExpressionSyntax exprToReplace = ies . Expression ;
273+ if ( exprToReplace is MemberAccessExpressionSyntax maes ) {
274+ var newName = SyntaxFactory . IdentifierName ( setMethodName ) . WithTriviaFrom ( maes . Name ) ;
275+ var stripThis = maes . Expression is ThisExpressionSyntax
276+ && node . Left . SkipIntoParens ( ) is not VBSyntax . MemberAccessExpressionSyntax {
277+ Expression : not ( VBSyntax . MeExpressionSyntax or VBSyntax . MyClassExpressionSyntax )
278+ } ;
279+ exprToReplace = stripThis ? newName . WithTriviaFrom ( maes ) : maes . WithName ( newName ) ;
280+ } else if ( exprToReplace is IdentifierNameSyntax ) {
281+ exprToReplace = SyntaxFactory . IdentifierName ( setMethodName ) . WithTriviaFrom ( exprToReplace ) ;
282+ }
283+ var newArgList = ies . ArgumentList . AddArguments ( SyntaxFactory . Argument ( rhs ) ) ;
284+ var newLhs = ies . WithExpression ( exprToReplace ) . WithArgumentList ( newArgList ) ;
285+ var postAssign = GetPostAssignmentStatements ( node ) ;
286+ return postAssign . Insert ( 0 , SyntaxFactory . ExpressionStatement ( newLhs ) ) ;
287+ }
288+ return SingleStatement ( lhs ) ;
289+ }
290+
291+ var assignment = SyntaxFactory . AssignmentExpression ( kind , lhs , rhs ) ;
254292 var postAssignment = GetPostAssignmentStatements ( node ) ;
255293 return postAssignment . Insert ( 0 , SyntaxFactory . ExpressionStatement ( assignment ) ) ;
256294 }
0 commit comments