Skip to content

Commit

Permalink
Add nullable annotations to NullableWalker (#45640)
Browse files Browse the repository at this point in the history
  • Loading branch information
cston authored Jul 31, 2020
1 parent 5a928ed commit 552de9a
Show file tree
Hide file tree
Showing 12 changed files with 687 additions and 657 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed partial class BoundExpressionWithNullability : BoundExpression
{
public BoundExpressionWithNullability(SyntaxNode syntax, BoundExpression expression, NullableAnnotation nullableAnnotation, TypeSymbol type)
public BoundExpressionWithNullability(SyntaxNode syntax, BoundExpression expression, NullableAnnotation nullableAnnotation, TypeSymbol? type)
: this(syntax, expression, nullableAnnotation, type, hasErrors: false)
{
IsSuppressed = expression.IsSuppressed;
Expand Down
2 changes: 2 additions & 0 deletions src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,8 @@
</Node>

<Node Name="BoundNullCoalescingOperator" Base="BoundExpression">
<!-- Non-null type is required for this node kind -->
<Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/>
<Field Name="LeftOperand" Type="BoundExpression"/>
<Field Name="RightOperand" Type="BoundExpression"/>
<Field Name="LeftConversion" Type="Conversion"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ private BoundNode VisitBinaryOperatorBase(BoundBinaryOperatorBase binaryOperator
{
currentBinary = stack.Pop();

bool foundInfo = _updatedNullabilities.TryGetValue(currentBinary, out (NullabilityInfo Info, TypeSymbol Type) infoAndType);
bool foundInfo = _updatedNullabilities.TryGetValue(currentBinary, out (NullabilityInfo Info, TypeSymbol? Type) infoAndType);
var right = (BoundExpression)Visit(currentBinary.Right);
var type = foundInfo ? infoAndType.Type : currentBinary.Type;

currentBinary = currentBinary switch
{
BoundBinaryOperator binary => binary.Update(binary.OperatorKind, binary.ConstantValueOpt, GetUpdatedSymbol(binary, binary.MethodOpt), binary.ResultKind, binary.OriginalUserDefinedOperatorsOpt, leftChild, right, type),
BoundBinaryOperator binary => binary.Update(binary.OperatorKind, binary.ConstantValueOpt, GetUpdatedSymbol(binary, binary.MethodOpt), binary.ResultKind, binary.OriginalUserDefinedOperatorsOpt, leftChild, right, type!),
// https://github.com/dotnet/roslyn/issues/35031: We'll need to update logical.LogicalOperator
BoundUserDefinedConditionalLogicalOperator logical => logical.Update(logical.OperatorKind, logical.LogicalOperator, logical.TrueOperator, logical.FalseOperator, logical.ResultKind, logical.OriginalUserDefinedOperatorsOpt, leftChild, right, type),
BoundUserDefinedConditionalLogicalOperator logical => logical.Update(logical.OperatorKind, logical.LogicalOperator, logical.TrueOperator, logical.FalseOperator, logical.ResultKind, logical.OriginalUserDefinedOperatorsOpt, leftChild, right, type!),
_ => throw ExceptionUtilities.UnexpectedValue(currentBinary.Kind),
};

Expand Down
16 changes: 8 additions & 8 deletions src/Compilers/CSharp/Portable/FlowAnalysis/LocalDataFlowPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable enable

using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
Expand Down Expand Up @@ -58,7 +61,7 @@ internal interface ILocalDataFlowState : ILocalState

protected LocalDataFlowPass(
CSharpCompilation compilation,
Symbol member,
Symbol? member,
BoundNode node,
EmptyStructTypeCache emptyStructs,
bool trackUnassignments,
Expand Down Expand Up @@ -113,7 +116,6 @@ protected virtual bool IsEmptyStructType(TypeSymbol type)
return _emptyStructTypeCache.IsEmptyStructType(type);
}

#nullable enable
/// <summary>
/// Force a variable to have a slot. Returns -1 if the variable has an empty struct type.
/// </summary>
Expand Down Expand Up @@ -171,7 +173,6 @@ protected virtual int GetOrCreateSlot(Symbol symbol, int containingSlot = 0, boo

return slot;
}
#nullable restore

private int GetSlotDepth(int slot)
{
Expand Down Expand Up @@ -199,8 +200,7 @@ private int GetSlotDepth(int slot)
/// </summary>
private int DescendThroughTupleRestFields(ref Symbol symbol, int containingSlot, bool forceContainingSlotsToExist)
{
var fieldSymbol = symbol as TupleFieldSymbol;
if ((object)fieldSymbol != null)
if (symbol is TupleFieldSymbol fieldSymbol)
{
TypeSymbol containingType = symbol.ContainingType;

Expand Down Expand Up @@ -236,7 +236,7 @@ private int DescendThroughTupleRestFields(ref Symbol symbol, int containingSlot,
return containingSlot;
}

protected abstract bool TryGetReceiverAndMember(BoundExpression expr, out BoundExpression receiver, out Symbol member);
protected abstract bool TryGetReceiverAndMember(BoundExpression expr, out BoundExpression? receiver, [NotNullWhen(true)] out Symbol? member);

protected Symbol GetNonMemberSymbol(int slot)
{
Expand Down Expand Up @@ -271,7 +271,7 @@ protected virtual int MakeSlot(BoundExpression node)
case BoundKind.FieldAccess:
case BoundKind.EventAccess:
case BoundKind.PropertyAccess:
if (TryGetReceiverAndMember(node, out BoundExpression receiver, out Symbol member))
if (TryGetReceiverAndMember(node, out BoundExpression? receiver, out Symbol? member))
{
Debug.Assert((receiver is null) != member.RequiresInstanceReceiver());
return MakeMemberSlot(receiver, member);
Expand All @@ -283,7 +283,7 @@ protected virtual int MakeSlot(BoundExpression node)
return -1;
}

protected int MakeMemberSlot(BoundExpression receiverOpt, Symbol member)
protected int MakeMemberSlot(BoundExpression? receiverOpt, Symbol member)
{
int containingSlot;
if (member.RequiresInstanceReceiver())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ internal sealed partial class NullableWalker
/// </summary>
private sealed class DebugVerifier : BoundTreeWalker
{
private readonly ImmutableDictionary<BoundExpression, (NullabilityInfo Info, TypeSymbol Type)> _analyzedNullabilityMap;
private readonly ImmutableDictionary<BoundExpression, (NullabilityInfo Info, TypeSymbol? Type)> _analyzedNullabilityMap;
private readonly SnapshotManager? _snapshotManager;
private readonly HashSet<BoundExpression> _visitedExpressions = new HashSet<BoundExpression>();
private int _recursionDepth;

private DebugVerifier(ImmutableDictionary<BoundExpression, (NullabilityInfo Info, TypeSymbol Type)> analyzedNullabilityMap, SnapshotManager? snapshotManager)
private DebugVerifier(ImmutableDictionary<BoundExpression, (NullabilityInfo Info, TypeSymbol? Type)> analyzedNullabilityMap, SnapshotManager? snapshotManager)
{
_analyzedNullabilityMap = analyzedNullabilityMap;
_snapshotManager = snapshotManager;
Expand All @@ -34,7 +34,7 @@ protected override bool ConvertInsufficientExecutionStackExceptionToCancelledByS
return false; // Same behavior as NullableWalker
}

public static void Verify(ImmutableDictionary<BoundExpression, (NullabilityInfo Info, TypeSymbol Type)> analyzedNullabilityMap, SnapshotManager? snapshotManagerOpt, BoundNode node)
public static void Verify(ImmutableDictionary<BoundExpression, (NullabilityInfo Info, TypeSymbol? Type)> analyzedNullabilityMap, SnapshotManager? snapshotManagerOpt, BoundNode node)
{
var verifier = new DebugVerifier(analyzedNullabilityMap, snapshotManagerOpt);
verifier.Visit(node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private SnapshotManager(ImmutableArray<SharedWalkerState> walkerSharedStates, Im
int position,
BoundNode nodeToAnalyze,
Binder binder,
ImmutableDictionary<BoundExpression, (NullabilityInfo, TypeSymbol)>.Builder analyzedNullabilityMap,
ImmutableDictionary<BoundExpression, (NullabilityInfo, TypeSymbol?)>.Builder analyzedNullabilityMap,
SnapshotManager.Builder newManagerOpt)
{
Snapshot incrementalSnapshot = GetSnapshotForPosition(position);
Expand Down Expand Up @@ -225,7 +225,7 @@ internal void ExitWalker(SharedWalkerState stableState, int previousSlot)
_currentWalkerSlot = previousSlot;
}

internal void TakeIncrementalSnapshot(BoundNode node, LocalState currentState)
internal void TakeIncrementalSnapshot(BoundNode? node, LocalState currentState)
{
if (node == null || node.WasCompilerGenerated)
{
Expand Down
Loading

0 comments on commit 552de9a

Please sign in to comment.