/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_RedimClause.vb
105 строк
6 KB
AlekseyTs
Ensure proper receiver value is used for a constrained call invocation (#70401)
02 ноя 2023, 01:39
Не верифицирован
02 ноя 2023, 01:39
0d04411
Код
Авторство
О чём код?
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable Imports System.Diagnostics Imports System.Runtime.InteropServices Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports TypeKind = Microsoft.CodeAnalysis.TypeKind Namespace Microsoft.CodeAnalysis.VisualBasic Partial Friend NotInheritable Class LocalRewriter Public Overrides Function VisitRedimClause(node As BoundRedimClause) As BoundNode ' array type must be known if the node is valid Debug.Assert(node.ArrayTypeOpt IsNot Nothing) ' build expression returning created (and optionally initialized) array Dim valueBeingAssigned As BoundExpression = New BoundArrayCreation(node.Syntax, node.Indices, Nothing, node.ArrayTypeOpt) Dim temporaries As ArrayBuilder(Of SynthesizedLocal) = Nothing Dim assignmentTarget = node.Operand Dim useSiteInfo = GetNewCompoundUseSiteInfo() Dim copyArrayUtilityMethod As MethodSymbol = Nothing If node.Preserve AndAlso TryGetWellknownMember(copyArrayUtilityMethod, WellKnownMember.Microsoft_VisualBasic_CompilerServices_Utils__CopyArray, node.Syntax) Then ' build a call to Microsoft.VisualBasic.CompilerServices.Utils.CopyArray ' use the operand twice temporaries = ArrayBuilder(Of SynthesizedLocal).GetInstance() Dim result As UseTwiceRewriter.Result = UseTwiceRewriter.UseTwice(Me._currentMethodOrLambda, assignmentTarget, isForRegularCompoundAssignment:=True, temporaries) ' the first to be used as an assignment target assignmentTarget = result.First ' the second will be used for accessing the array's current value Dim arrayValueAccess = result.Second ' make an r-value from array value access If arrayValueAccess.Kind = BoundKind.PropertyAccess Then arrayValueAccess = DirectCast(arrayValueAccess, BoundPropertyAccess).SetAccessKind(PropertyAccessKind.Get) ElseIf arrayValueAccess.IsLateBound() Then arrayValueAccess = arrayValueAccess.SetLateBoundAccessKind(LateBoundAccessKind.Get) Else arrayValueAccess = arrayValueAccess.MakeRValue() End If ' System.Array type Dim systemArray = copyArrayUtilityMethod.Parameters(0).Type ' add conversion arrayValueAccess = New BoundDirectCast(node.Syntax, arrayValueAccess, Conversions.ClassifyDirectCastConversion(arrayValueAccess.Type, systemArray, useSiteInfo), systemArray, Nothing) valueBeingAssigned = New BoundDirectCast(node.Syntax, valueBeingAssigned, Conversions.ClassifyDirectCastConversion(valueBeingAssigned.Type, systemArray, useSiteInfo), systemArray, Nothing) ' bind call to CopyArray valueBeingAssigned = New BoundCall(node.Syntax, copyArrayUtilityMethod, Nothing, Nothing, ImmutableArray.Create(Of BoundExpression)(arrayValueAccess, valueBeingAssigned), Nothing, systemArray) End If ' add conversion if needed valueBeingAssigned = New BoundDirectCast(node.Syntax, valueBeingAssigned, Conversions.ClassifyDirectCastConversion(valueBeingAssigned.Type, assignmentTarget.Type, useSiteInfo), assignmentTarget.Type, Nothing) _diagnostics.Add(node, useSiteInfo) ' adjust assignment target If assignmentTarget.Kind = BoundKind.PropertyAccess Then assignmentTarget = DirectCast(assignmentTarget, BoundPropertyAccess).SetAccessKind(PropertyAccessKind.Set) ElseIf assignmentTarget.IsLateBound() Then assignmentTarget = assignmentTarget.SetLateBoundAccessKind(LateBoundAccessKind.Set) End If ' create assignment operator Dim assignmentOperator As BoundExpression = New BoundAssignmentOperator(node.Syntax, assignmentTarget, valueBeingAssigned, True) ' if there are any temporaries, wrap it in If temporaries IsNot Nothing Then If temporaries.Count > 0 Then assignmentOperator = New BoundSequence(node.Syntax, StaticCast(Of LocalSymbol).From(temporaries.ToImmutableAndFree()), ImmutableArray.Create(Of BoundExpression)(assignmentOperator), Nothing, If(assignmentOperator.Type.IsVoidType(), assignmentOperator.Type, Compilation.GetSpecialType(SpecialType.System_Void))) Else temporaries.Free() End If End If ' create assignment statement Return Visit(New BoundExpressionStatement(node.Syntax, assignmentOperator)) End Function End Class End Namespace