Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nullable annotations to NullableWalker #45640

Merged
merged 16 commits into from
Jul 31, 2020
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))
Copy link
Member

@333fred 333fred Jul 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

member [](start = 97, length = 6)

Can we add an attribute? #Closed

{
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,
333fred marked this conversation as resolved.
Show resolved Hide resolved
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