/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/BoundTree/BoundAssignmentOperator.vb
149 строк
8 KB
Jonathon Marolf
update headers
23 янв 2020, 04:01
Не верифицирован
23 янв 2020, 04:01
91571a3
Код
Авторство
О чём код?
' 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 Microsoft.CodeAnalysis.VisualBasic.Symbols Namespace Microsoft.CodeAnalysis.VisualBasic Partial Friend NotInheritable Class BoundAssignmentOperator Inherits BoundExpression Public Sub New(syntax As SyntaxNode, left As BoundExpression, right As BoundExpression, suppressObjectClone As Boolean, type As TypeSymbol, Optional hasErrors As Boolean = False) Me.New(syntax, left, leftOnTheRightOpt:=Nothing, right:=right, suppressObjectClone:=suppressObjectClone, type:=type, hasErrors:=hasErrors) End Sub Public Sub New(syntax As SyntaxNode, left As BoundExpression, right As BoundExpression, suppressObjectClone As Boolean, Optional hasErrors As Boolean = False) Me.New(syntax, left, leftOnTheRightOpt:=Nothing, right:=right, suppressObjectClone:=suppressObjectClone, hasErrors:=hasErrors) End Sub Public Sub New( syntax As SyntaxNode, left As BoundExpression, leftOnTheRightOpt As BoundCompoundAssignmentTargetPlaceholder, right As BoundExpression, suppressObjectClone As Boolean, Optional hasErrors As Boolean = False ) 'NOTE: even though in general assignment returns the value of the Right, ' the type of the operator is the type of the Left as that is the type of the location ' into which the Right is stored. ' ' Dim x as Long ' Dim y as byte = 1 ' Dim z := x := y ' if this was legal assignment of an assignment, z would have type Long ' ' properties and latebound assignments are special cased since they are semantically statements ' 'TODO: it could make sense to have BoundAssignmentStatement just for the purpose of ' binding assignments. It would make invariants for both BoundAssignmentExpression and BoundAssignmentStatement simpler. Me.New(syntax, left, leftOnTheRightOpt, right:=right, suppressObjectClone:=suppressObjectClone, type:=If(left.IsPropertyOrXmlPropertyAccess(), left.GetPropertyOrXmlProperty().ContainingAssembly.GetSpecialType(SpecialType.System_Void), If(left.IsLateBound, left.Type.ContainingAssembly.GetSpecialType(SpecialType.System_Void), left.Type)), hasErrors:=hasErrors) End Sub #If DEBUG Then Private Sub Validate() Debug.Assert(Left.Type IsNot Nothing) If Not HasErrors Then Debug.Assert(Left.IsLValue OrElse Left.IsPropertyOrXmlPropertyAccess() OrElse Left.IsLateBound) Select Case Left.Kind Case BoundKind.PropertyAccess Dim propertyAccess = DirectCast(Left, BoundPropertyAccess) Debug.Assert(propertyAccess.AccessKind = If(DirectCast(Left, BoundPropertyAccess).PropertySymbol.ReturnsByRef, PropertyAccessKind.Get, If(LeftOnTheRightOpt Is Nothing, PropertyAccessKind.Set, PropertyAccessKind.Set Or PropertyAccessKind.Get))) Debug.Assert(Type.IsVoidType()) Case BoundKind.XmlMemberAccess Debug.Assert(Left.GetAccessKind() = If(LeftOnTheRightOpt Is Nothing, PropertyAccessKind.Set, PropertyAccessKind.Set Or PropertyAccessKind.Get)) Debug.Assert(Type.IsVoidType()) Case BoundKind.LateMemberAccess Debug.Assert(Left.GetLateBoundAccessKind() = If(LeftOnTheRightOpt Is Nothing, LateBoundAccessKind.Set, LateBoundAccessKind.Set Or LateBoundAccessKind.Get)) Case BoundKind.LateInvocation Dim invocation = DirectCast(Left, BoundLateInvocation) Debug.Assert(invocation.AccessKind = If(LeftOnTheRightOpt Is Nothing, LateBoundAccessKind.Set, LateBoundAccessKind.Set Or LateBoundAccessKind.Get)) If Not invocation.ArgumentsOpt.IsDefault Then For Each arg In invocation.ArgumentsOpt Debug.Assert(Not arg.IsSupportingAssignment()) Next End If Case Else Debug.Assert(Not Left.IsLateBound) End Select Debug.Assert(Left.Type.IsSameTypeIgnoringAll(Right.Type)) End If Right.AssertRValue() Debug.Assert(Left.IsPropertyOrXmlPropertyAccess() OrElse Left.IsLateBound OrElse IsByRefPropertyGet(Left) OrElse Left.Type.IsSameTypeIgnoringAll(Type) OrElse (Type.IsVoidType() AndAlso Syntax.Kind = SyntaxKind.MidAssignmentStatement) OrElse (Left.Kind = BoundKind.FieldAccess AndAlso DirectCast(Left, BoundFieldAccess).FieldSymbol.AssociatedSymbol.Kind = SymbolKind.Property AndAlso Type.IsVoidType())) ' If LeftOnTheRightOpt is not nothing and this isn't a mid statement, then we assert the shape that IOperation is expecting ' compound expressions to have If LeftOnTheRightOpt IsNot Nothing Then ' The right node is either a BoundUserDefinedBinaryOperator or a BoundBinaryOperator, or a conversion on top of them Dim rightNode = Right If rightNode.Kind = BoundKind.Conversion Then rightNode = DirectCast(rightNode, BoundConversion).Operand If rightNode.Kind = BoundKind.UserDefinedConversion Then rightNode = DirectCast(rightNode, BoundUserDefinedConversion).Operand End If End If If rightNode.Kind <> BoundKind.MidResult Then Debug.Assert(rightNode.Kind = BoundKind.BinaryOperator OrElse rightNode.Kind = BoundKind.UserDefinedBinaryOperator) Dim leftNode As BoundNode = Nothing If rightNode.Kind = BoundKind.BinaryOperator Then leftNode = DirectCast(rightNode, BoundBinaryOperator).Left Else Dim boundUserDefinedOperator = DirectCast(rightNode, BoundUserDefinedBinaryOperator) If boundUserDefinedOperator.UnderlyingExpression.Kind = BoundKind.Call Then leftNode = boundUserDefinedOperator.Left Else leftNode = DirectCast(boundUserDefinedOperator.UnderlyingExpression, BoundBadExpression).ChildBoundNodes(0) End If End If ' The left node of the binary operation is either the same node as in LeftOnTheRightOpt, or is a conversion on top of that node If leftNode.Kind = BoundKind.Conversion Then leftNode = DirectCast(leftNode, BoundConversion).Operand If leftNode.Kind = BoundKind.UserDefinedConversion Then leftNode = DirectCast(leftNode, BoundUserDefinedConversion).Operand End If End If Debug.Assert(leftNode Is LeftOnTheRightOpt) End If End If End Sub Private Shared Function IsByRefPropertyGet(node As BoundExpression) As Boolean Dim value = TryCast(TryCast(node, BoundCall)?.Method?.AssociatedSymbol, PropertySymbol)?.ReturnsByRef Return value.HasValue AndAlso value.Value = True End Function #End If End Class End Namespace