提交 927e8181 编写于 作者: N Nat Ayewah

Merge remote-tracking branch 'upstream/dev15-preview-5' into...

Merge remote-tracking branch 'upstream/dev15-preview-5' into merge-dev15-preview-5-into-master20160915-150105
......@@ -33,7 +33,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private Sub MakeSlots(parameters As ImmutableArray(Of ParameterSymbol))
For Each parameter In parameters
MakeSlot(parameter)
GetOrCreateSlot(parameter)
Next
End Sub
......
......@@ -105,14 +105,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
MyBase.InitForScan()
For Each parameter In MethodParameters
MakeSlot(parameter)
GetOrCreateSlot(parameter)
Next
Me._alreadyReported = BitVector.Empty ' no variables yet reported unassigned
Me.EnterParameters(MethodParameters) ' with parameters assigned
Dim methodMeParameter = Me.MeParameter ' and with 'Me' assigned as well
If methodMeParameter IsNot Nothing Then
Me.MakeSlot(methodMeParameter)
Me.GetOrCreateSlot(methodMeParameter)
Me.EnterParameter(methodMeParameter)
End If
......@@ -134,7 +134,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
'
If initiallyAssignedVariables IsNot Nothing Then
For Each local In initiallyAssignedVariables
SetSlotAssigned(MakeSlot(local))
SetSlotAssigned(GetOrCreateSlot(local))
Next
End If
End Sub
......@@ -371,16 +371,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' in an earlier phase as "use before declaration". That allows us to avoid giving slots to local variables before
''' processing their declarations.
''' </summary>
Protected Function VariableSlot(local As Symbol, Optional containingSlot As Integer = 0) As Integer
Protected Function VariableSlot(symbol As Symbol, Optional containingSlot As Integer = 0) As Integer
If local Is Nothing Then
containingSlot = DescendThroughTupleRestFields(symbol, containingSlot, forceContainingSlotsToExist:=False)
If symbol Is Nothing Then
' NOTE: This point may be hit in erroneous code, like
' referencing instance members from static methods
Return SlotKind.NotTracked
End If
Dim slot As Integer
Return If((_variableSlot.TryGetValue(New VariableIdentifier(local, containingSlot), slot)), slot, SlotKind.NotTracked)
Return If((_variableSlot.TryGetValue(New VariableIdentifier(symbol, containingSlot), slot)), slot, SlotKind.NotTracked)
End Function
......@@ -394,7 +396,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Case BoundKind.MeReference, BoundKind.MyBaseReference, BoundKind.MyClassReference
If MeParameter IsNot Nothing Then
result.Append(MakeSlot(MeParameter))
result.Append(GetOrCreateSlot(MeParameter))
End If
Case BoundKind.Local
......@@ -403,20 +405,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If local.DeclarationKind = LocalDeclarationKind.AmbiguousLocals Then
' multiple locals
For Each loc In DirectCast(local, AmbiguousLocalsPseudoSymbol).Locals
result.Append(MakeSlot(loc))
result.Append(GetOrCreateSlot(loc))
Next
Else
' just one simple local
result.Append(MakeSlot(local))
result.Append(GetOrCreateSlot(local))
End If
Case BoundKind.RangeVariable
result.Append(MakeSlot(DirectCast(node, BoundRangeVariable).RangeVariable))
result.Append(GetOrCreateSlot(DirectCast(node, BoundRangeVariable).RangeVariable))
Case BoundKind.Parameter
result.Append(MakeSlot(DirectCast(node, BoundParameter).ParameterSymbol))
result.Append(GetOrCreateSlot(DirectCast(node, BoundParameter).ParameterSymbol))
Case BoundKind.FieldAccess
Dim fieldAccess = DirectCast(node, BoundFieldAccess)
......@@ -437,7 +439,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' update slots, reuse collection
' NOTE: we don't filter out SlotKind.NotTracked values
For i = 0 To result.Count - 1
result(i) = MakeSlot(fieldAccess.FieldSymbol, result(0))
result(i) = GetOrCreateSlot(fieldAccess.FieldSymbol, result(0))
Next
Case BoundKind.WithLValueExpressionPlaceholder, BoundKind.WithRValueExpressionPlaceholder
......@@ -454,24 +456,27 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' <summary>
''' Force a variable to have a slot.
''' </summary>
''' <param name = "local"></param>
''' <param name = "symbol"></param>
''' <returns></returns>
Protected Function MakeSlot(local As Symbol, Optional containingSlot As Integer = 0) As Integer
Protected Function GetOrCreateSlot(symbol As Symbol, Optional containingSlot As Integer = 0) As Integer
containingSlot = DescendThroughTupleRestFields(symbol, containingSlot, forceContainingSlotsToExist:=True)
If containingSlot = SlotKind.NotTracked Then
Return SlotKind.NotTracked
End If
' Check if the slot already exists
Dim varIdentifier As New VariableIdentifier(local, containingSlot)
Dim varIdentifier As New VariableIdentifier(symbol, containingSlot)
Dim slot As Integer
If Not _variableSlot.TryGetValue(varIdentifier, slot) Then
If local.Kind = SymbolKind.Local Then
Me._unusedVariables.Add(DirectCast(local, LocalSymbol))
If symbol.Kind = SymbolKind.Local Then
Me._unusedVariables.Add(DirectCast(symbol, LocalSymbol))
End If
Dim variableType As TypeSymbol = GetVariableType(local)
Dim variableType As TypeSymbol = GetVariableType(symbol)
If IsEmptyStructType(variableType) Then
Return SlotKind.NotTracked
......@@ -491,6 +496,46 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return slot
End Function
''' <summary>
''' Descends through Rest fields of a tuple if "symbol" is an extended field
''' As a result the "symbol" will be adjusted to be the field of the innermost tuple
''' and a corresponding containingSlot is returned.
''' Return value -1 indicates a failure which could happen for the following reasons
''' a) Rest field does not exist, which could happen in rare error scenarios involving broken ValueTuple types
''' b) Rest is not tracked already and forceSlotsToExist is false (otherwise we create slots on demand)
''' </summary>
Private Function DescendThroughTupleRestFields(ByRef symbol As Symbol, containingSlot As Integer, forceContainingSlotsToExist As Boolean) As Integer
Dim fieldSymbol = TryCast(symbol, TupleFieldSymbol)
If fieldSymbol IsNot Nothing Then
Dim containingType As TypeSymbol = DirectCast(symbol.ContainingType, TupleTypeSymbol).UnderlyingNamedType
' for tuple fields the variable identifier represents the underlying field
symbol = fieldSymbol.TupleUnderlyingField
' descend through Rest fields
' force corresponding slots if do not exist
While containingType <> symbol.ContainingType
Dim restField = TryCast(containingType.GetMembers(TupleTypeSymbol.RestFieldName).FirstOrDefault(), FieldSymbol)
If restField Is Nothing Then
Return -1
End If
If forceContainingSlotsToExist Then
containingSlot = GetOrCreateSlot(restField, containingSlot)
Else
If Not _variableSlot.TryGetValue(New VariableIdentifier(restField, containingSlot), containingSlot) Then
Return -1
End If
End If
containingType = restField.Type.GetTupleUnderlyingTypeOrSelf()
End While
End If
Return containingSlot
End Function
' In C#, we moved this cache to a separate cache held onto by the compilation, so we didn't
' recompute it each time.
'
......@@ -705,7 +750,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' exit while if there is at least one child with a slot which is not assigned
For Each childSymbol In GetStructInstanceFields(parentStructType)
Dim childSlot = MakeSlot(childSymbol, parentSlot)
Dim childSlot = GetOrCreateSlot(childSymbol, parentSlot)
If childSlot <> SlotKind.NotTracked AndAlso Not state.IsAssigned(childSlot) Then
Exit While
End If
......@@ -793,6 +838,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' only fields
If member.Kind = SymbolKind.Field Then
Dim field = DirectCast(member, FieldSymbol)
' Do not report virtual tuple fields.
' They are additional aliases to the fields of the underlying struct or nested extensions.
' and as such are already accounted for via the nonvirtual fields.
If field.IsVirtualTupleField Then
Continue For
End If
' only instance fields
If Not ShouldIgnoreStructField(field) Then
' NOTE: DO NOT skip fields of intrinsic types if _trackStructsWithIntrinsicTypedFields is True
......@@ -889,7 +942,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Next
Else
Dim slot As Integer = MakeSlot(symbol)
Dim slot As Integer = GetOrCreateSlot(symbol)
If slot >= Me.State.Assigned.Capacity Then
Normalize(Me.State)
End If
......@@ -971,7 +1024,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return True
End If
' NOTE: unassignedSlot must have been set by previous call to IsAssigned(...)
unassignedSlot = MakeSlot(fieldAccess.FieldSymbol, unassignedSlot)
unassignedSlot = GetOrCreateSlot(fieldAccess.FieldSymbol, unassignedSlot)
Case BoundKind.WithLValueExpressionPlaceholder, BoundKind.WithRValueExpressionPlaceholder
Dim substitute As BoundExpression = Me.GetPlaceholderSubstitute(DirectCast(node, BoundValuePlaceholderBase))
......@@ -1262,7 +1315,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim local = DirectCast(node, BoundLocalDeclaration)
Debug.Assert(local.InitializerOpt Is value OrElse local.InitializedByAsNew)
Dim symbol = local.LocalSymbol
Dim slot As Integer = MakeSlot(symbol)
Dim slot As Integer = GetOrCreateSlot(symbol)
Dim written As Boolean = assigned OrElse Not Me.State.Reachable
SetSlotState(slot, written)
' Note write if the local has an initializer or if it is part of an as-new.
......@@ -1273,7 +1326,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim forStatement = DirectCast(node, BoundForStatement)
Dim symbol = forStatement.DeclaredOrInferredLocalOpt
Debug.Assert(symbol IsNot Nothing)
Dim slot As Integer = MakeSlot(symbol)
Dim slot As Integer = GetOrCreateSlot(symbol)
Dim written As Boolean = assigned OrElse Not Me.State.Reachable
SetSlotState(slot, written)
......@@ -1286,7 +1339,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
' Regular variable
Dim slot As Integer = MakeSlot(symbol)
Dim slot As Integer = GetOrCreateSlot(symbol)
SetSlotState(slot, assigned)
If symbol.IsFunctionValue Then
SetSlotState(SlotKind.FunctionValue, assigned)
......@@ -1298,13 +1351,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Case BoundKind.Parameter
Dim local = DirectCast(node, BoundParameter)
Dim symbol = local.ParameterSymbol
Dim slot As Integer = MakeSlot(symbol)
Dim slot As Integer = GetOrCreateSlot(symbol)
SetSlotState(slot, assigned)
If assigned Then NoteWrite(symbol, value)
Case BoundKind.MeReference
' var local = node as BoundThisReference;
Dim slot As Integer = MakeSlot(MeParameter)
Dim slot As Integer = GetOrCreateSlot(MeParameter)
SetSlotState(slot, assigned)
If assigned Then NoteWrite(MeParameter, value)
......@@ -1410,7 +1463,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private Sub VisitCatchBlockInternal(catchBlock As BoundCatchBlock, ByRef finallyState As LocalState)
Dim local = catchBlock.LocalOpt
If local IsNot Nothing Then
MakeSlot(local)
GetOrCreateSlot(local)
End If
Dim exceptionSource = catchBlock.ExceptionSourceOpt
......@@ -1533,7 +1586,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
' Create a slot for the declared variable to be able to track it.
Dim slot As Integer = MakeSlot(local)
Dim slot As Integer = GetOrCreateSlot(local)
'If initializer is a lambda, we need to treat the local as assigned within the lambda.
Assign(node, node.InitializerOpt,
......@@ -1603,7 +1656,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim localVariables = node.Locals
For Each local In localVariables
If local.IsImplicitlyDeclared Then
SetSlotState(MakeSlot(local), ConsiderLocalInitiallyAssigned(local))
SetSlotState(GetOrCreateSlot(local), ConsiderLocalInitiallyAssigned(local))
End If
Next
......@@ -1773,7 +1826,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' if the for each statement declared a variable explicitly or by using local type inference we'll
' need to create a new slot for the new variable that is initially unassigned.
If node.DeclaredOrInferredLocalOpt IsNot Nothing Then
Dim slot As Integer = MakeSlot(node.DeclaredOrInferredLocalOpt) 'not initially assigned
Dim slot As Integer = GetOrCreateSlot(node.DeclaredOrInferredLocalOpt) 'not initially assigned
Assign(node, Nothing, ConsiderLocalInitiallyAssigned(node.DeclaredOrInferredLocalOpt))
End If
End Sub
......@@ -1802,7 +1855,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If variableDeclarations.Kind = BoundKind.AsNewLocalDeclarations Then
For Each variableDeclaration In DirectCast(variableDeclarations, BoundAsNewLocalDeclarations).LocalDeclarations
Dim local = variableDeclaration.LocalSymbol
Dim slot = MakeSlot(local)
Dim slot = GetOrCreateSlot(local)
If slot >= 0 Then
SetSlotAssigned(slot)
NoteWrite(local, Nothing)
......@@ -1812,7 +1865,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Next
Else
Dim local = DirectCast(variableDeclarations, BoundLocalDeclaration).LocalSymbol
Dim slot = MakeSlot(local)
Dim slot = GetOrCreateSlot(local)
If slot >= 0 Then
SetSlotAssigned(slot)
NoteWrite(local, Nothing)
......@@ -1973,7 +2026,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' An initializer might access the declared variables in the initializer and therefore need to create a slot to
' track them
For Each localDeclaration In declarations
MakeSlot(localDeclaration.LocalSymbol)
GetOrCreateSlot(localDeclaration.LocalSymbol)
Next
' NOTE: in case 'variableIsUsedDirectlyAndIsAlwaysAssigned' is set it must be
......
......@@ -66,7 +66,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' that flows in is assigned at the beginning of the loop. If it isn't, then it must
' be in a loop and flow out of the region in that loop (and into the region inside the loop).
For Each variable As Symbol In _dataFlowsIn
Dim slot As Integer = Me.MakeSlot(variable)
Dim slot As Integer = Me.GetOrCreateSlot(variable)
If Not Me.State.IsAssigned(slot) AndAlso variable.Kind <> SymbolKind.RangeVariable AndAlso
(variable.Kind <> SymbolKind.Local OrElse Not DirectCast(variable, LocalSymbol).IsStatic) Then
_dataFlowsOut.Add(variable)
......
......@@ -150,7 +150,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Protected Overrides Sub EnterParameter(parameter As ParameterSymbol)
' parameters are NOT initially assigned here - if that is a problem, then
' the parameters must be captured.
MakeSlot(parameter)
GetOrCreateSlot(parameter)
' Instead of analyzing which parameters are actually being referenced
' we add all of them; this might need to be revised later
......@@ -220,7 +220,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim result As BoundNode = Nothing
For Each local In node.Locals
SetSlotState(MakeSlot(local), True)
SetSlotState(GetOrCreateSlot(local), True)
Next
result = MyBase.VisitSequence(node)
For Each local In node.Locals
......
......@@ -28,6 +28,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Friend Const RestPosition As Integer = 8
Friend Const TupleTypeName As String = "ValueTuple"
Friend Const RestFieldName As String = "Rest"
Private Shared ReadOnly tupleTypes As WellKnownType() = New WellKnownType() {WellKnownType.System_ValueTuple_T1, WellKnownType.System_ValueTuple_T2, WellKnownType.System_ValueTuple_T3, WellKnownType.System_ValueTuple_T4, WellKnownType.System_ValueTuple_T5, WellKnownType.System_ValueTuple_T6, WellKnownType.System_ValueTuple_T7, WellKnownType.System_ValueTuple_TRest}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册