未验证 提交 0610c798 编写于 作者: A AlekseyTs 提交者: GitHub

Remove remaining artifacts of symbol-centric NonNullTypes context. (#31607)

Closes #30171.
Closes #29838.
上级 ac7a0d00
......@@ -11,13 +11,22 @@ internal struct NamespaceOrTypeOrAliasSymbolWithAnnotations
{
private readonly TypeSymbolWithAnnotations _type;
private readonly Symbol _symbol;
private readonly bool _isNullableEnabled;
private NamespaceOrTypeOrAliasSymbolWithAnnotations(TypeSymbolWithAnnotations type, Symbol symbol)
private NamespaceOrTypeOrAliasSymbolWithAnnotations(TypeSymbolWithAnnotations type)
{
Debug.Assert(type.IsNull != (symbol is null));
Debug.Assert(!(symbol is TypeSymbol));
Debug.Assert(!type.IsNull);
_type = type;
_symbol = null;
_isNullableEnabled = false; // Not meaningful for a TypeSymbolWithAnnotations, it already baked the fact into its content.
}
private NamespaceOrTypeOrAliasSymbolWithAnnotations(Symbol symbol, bool isNullableEnabled)
{
Debug.Assert(!(symbol is TypeSymbol));
_type = default;
_symbol = symbol;
_isNullableEnabled = isNullableEnabled;
}
internal TypeSymbolWithAnnotations Type => _type;
......@@ -27,7 +36,16 @@ private NamespaceOrTypeOrAliasSymbolWithAnnotations(TypeSymbolWithAnnotations ty
internal NamespaceOrTypeSymbol NamespaceOrTypeSymbol => Symbol as NamespaceOrTypeSymbol;
internal bool IsDefault => _type.IsNull && _symbol is null;
internal static NamespaceOrTypeOrAliasSymbolWithAnnotations CreateUnannotated(INonNullTypesContext nonNullTypesContext, Symbol symbol)
internal bool IsNullableEnabled
{
get
{
Debug.Assert(_symbol?.Kind == SymbolKind.Alias); // Not meaningful to use this property otherwise
return _isNullableEnabled;
}
}
internal static NamespaceOrTypeOrAliasSymbolWithAnnotations CreateUnannotated(bool isNullableEnabled, Symbol symbol)
{
if (symbol is null)
{
......@@ -35,13 +53,13 @@ internal static NamespaceOrTypeOrAliasSymbolWithAnnotations CreateUnannotated(IN
}
var type = symbol as TypeSymbol;
return type is null ?
new NamespaceOrTypeOrAliasSymbolWithAnnotations(default, symbol) :
new NamespaceOrTypeOrAliasSymbolWithAnnotations(TypeSymbolWithAnnotations.Create(nonNullTypesContext, type), null);
new NamespaceOrTypeOrAliasSymbolWithAnnotations(symbol, isNullableEnabled) :
new NamespaceOrTypeOrAliasSymbolWithAnnotations(TypeSymbolWithAnnotations.Create(isNullableEnabled, type));
}
public static implicit operator NamespaceOrTypeOrAliasSymbolWithAnnotations(TypeSymbolWithAnnotations type)
{
return new NamespaceOrTypeOrAliasSymbolWithAnnotations(type, null);
return new NamespaceOrTypeOrAliasSymbolWithAnnotations(type);
}
}
}
......
......@@ -216,7 +216,27 @@ internal virtual Symbol ContainingMemberOrLambda
/// <summary>
/// Are we in a context where un-annotated types should be interpreted as non-null?
/// </summary>
internal INonNullTypesContext NonNullTypesContext => (Flags & BinderFlags.InEEMethodBinder) == 0 ? ContainingMember().OriginalDefinition : NonNullTypesTrueContext.Instance;
internal bool IsNullableEnabled(SyntaxTree syntaxTree, int position)
{
bool? fromTree = ((CSharpSyntaxTree)syntaxTree).GetNullableDirectiveState(position);
if (fromTree != null)
{
return fromTree.GetValueOrDefault();
}
return IsNullableGloballyEnabled();
}
internal bool IsNullableEnabled(SyntaxToken token)
{
return IsNullableEnabled(token.SyntaxTree, token.SpanStart);
}
internal virtual bool IsNullableGloballyEnabled()
{
return Next.IsNullableGloballyEnabled();
}
/// <summary>
/// Is the contained code within a member method body?
......
......@@ -116,13 +116,24 @@ internal partial class Binder
diagnostics.Add(ErrorCode.ERR_RefValBoundMustBeFirst, syntax.GetFirstToken().GetLocation());
}
SyntaxToken questionToken = ((ClassOrStructConstraintSyntax)syntax).QuestionToken;
var constraintSyntax = (ClassOrStructConstraintSyntax)syntax;
SyntaxToken questionToken = constraintSyntax.QuestionToken;
if (questionToken.IsKind(SyntaxKind.QuestionToken))
{
constraints |= TypeParameterConstraintKind.NullableReferenceType;
diagnostics.Add(new LazyMissingNonNullTypesContextDiagnosticInfo(Compilation, NonNullTypesContext, type: default), questionToken.GetLocation());
DiagnosticInfo info = LazyMissingNonNullTypesContextDiagnosticInfo.ReportNullableReferenceTypesIfNeeded(Compilation, IsNullableEnabled(questionToken));
if (!(info is null))
{
diagnostics.Add(info, questionToken.GetLocation());
}
}
else if (IsNullableEnabled(constraintSyntax.ClassOrStructKeyword))
{
constraints |= TypeParameterConstraintKind.NotNullableReferenceType;
}
else
else
{
constraints |= TypeParameterConstraintKind.ReferenceType;
}
......
......@@ -340,13 +340,13 @@ private BoundExpression SetInferredType(BoundExpression expression, TypeSymbol t
case BoundKind.DeconstructionVariablePendingInference:
{
var pending = (DeconstructionVariablePendingInference)expression;
return pending.SetInferredType(TypeSymbolWithAnnotations.Create(NonNullTypesContext, type), this, diagnostics);
return pending.SetInferredType(TypeSymbolWithAnnotations.Create(type), this, diagnostics);
}
case BoundKind.DiscardExpression:
{
var pending = (BoundDiscardExpression)expression;
Debug.Assert((object)pending.Type == null);
return pending.SetInferredType(TypeSymbolWithAnnotations.Create(NonNullTypesContext, type));
return pending.SetInferredType(TypeSymbolWithAnnotations.Create(type));
}
default:
throw ExceptionUtilities.UnexpectedValue(expression.Kind);
......
......@@ -250,13 +250,13 @@ internal BoundExpression ConvertPatternExpression(TypeSymbol inputType, CSharpSy
TypeSymbolWithAnnotations declType = BindTypeOrVarKeyword(typeSyntax, diagnostics, out isVar, out aliasOpt);
if (isVar)
{
declType = TypeSymbolWithAnnotations.Create(NonNullTypesContext, operandType);
declType = TypeSymbolWithAnnotations.Create(operandType);
}
if (declType.IsNull)
{
Debug.Assert(hasErrors);
declType = TypeSymbolWithAnnotations.Create(NonNullTypesContext, this.CreateErrorType("var"));
declType = TypeSymbolWithAnnotations.Create(this.CreateErrorType("var"));
}
var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType.TypeSymbol);
......
......@@ -102,14 +102,14 @@ private NamespaceOrTypeOrAliasSymbolWithAnnotations BindTypeOrAliasOrVarKeyword(
{
if (syntax.IsVar)
{
var symbol = BindTypeOrAliasOrKeyword(syntax, diagnostics, out isVar);
var symbol = BindTypeOrAliasOrKeyword((IdentifierNameSyntax)syntax, diagnostics, out isVar);
if (isVar)
{
CheckFeatureAvailability(syntax, MessageID.IDS_FeatureImplicitLocal, diagnostics);
}
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(NonNullTypesContext, symbol);
return symbol;
}
else
{
......@@ -122,14 +122,14 @@ private NamespaceOrTypeOrAliasSymbolWithAnnotations BindTypeOrAliasOrUnmanagedKe
{
if (syntax.IsUnmanaged)
{
var symbol = BindTypeOrAliasOrKeyword(syntax, diagnostics, out isUnmanaged);
var symbol = BindTypeOrAliasOrKeyword((IdentifierNameSyntax)syntax, diagnostics, out isUnmanaged);
if (isUnmanaged)
{
CheckFeatureAvailability(syntax, MessageID.IDS_FeatureUnmanagedGenericTypeConstraint, diagnostics);
}
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(NonNullTypesContext, symbol);
return symbol;
}
else
{
......@@ -144,10 +144,10 @@ private NamespaceOrTypeOrAliasSymbolWithAnnotations BindTypeOrAliasOrUnmanagedKe
/// PREREQUISITE: syntax should be checked to match the keyword, like <see cref="TypeSyntax.IsVar"/> or <see cref="TypeSyntax.IsUnmanaged"/>.
/// Otherwise, call <see cref="Binder.BindTypeOrAlias(ExpressionSyntax, DiagnosticBag, ConsList{Symbol})"/> instead.
/// </summary>
private Symbol BindTypeOrAliasOrKeyword(TypeSyntax syntax, DiagnosticBag diagnostics, out bool isKeyword)
private NamespaceOrTypeOrAliasSymbolWithAnnotations BindTypeOrAliasOrKeyword(IdentifierNameSyntax syntax, DiagnosticBag diagnostics, out bool isKeyword)
{
// Keywords can only be IdentifierNameSyntax
var identifierValueText = ((IdentifierNameSyntax)syntax).Identifier.ValueText;
var identifierValueText = syntax.Identifier.ValueText;
Symbol symbol = null;
// Perform name lookup without generating diagnostics as it could possibly be a keyword in the current context.
......@@ -240,7 +240,8 @@ private Symbol BindTypeOrAliasOrKeyword(TypeSyntax syntax, DiagnosticBag diagnos
}
lookupResult.Free();
return symbol;
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(IsNullableEnabled(syntax.Identifier), symbol);
}
// Binds the given expression syntax as Type.
......@@ -355,11 +356,6 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS
var type = (NamedTypeSymbol)constructedType.TypeSymbol;
var location = syntax.Location;
var conversions = this.Conversions.WithNullability(includeNullability: true);
if (!ShouldCheckConstraintsNullability)
{
diagnostics.Add(new LazyNullableContraintChecksDiagnosticInfo(type, conversions, this.Compilation), location);
conversions = this.Conversions.WithNullability(includeNullability: false);
}
type.CheckConstraints(this.Compilation, conversions, location, diagnostics);
}
else if (constructedType.TypeSymbol.IsUnconstrainedTypeParameter())
......@@ -372,17 +368,16 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS
case SyntaxKind.PredefinedType:
{
var type = BindPredefinedTypeSymbol((PredefinedTypeSyntax)syntax, diagnostics);
return TypeSymbolWithAnnotations.Create(NonNullTypesContext, type);
var predefinedType = (PredefinedTypeSyntax)syntax;
var type = BindPredefinedTypeSymbol(predefinedType, diagnostics);
return TypeSymbolWithAnnotations.Create(IsNullableEnabled(predefinedType.Keyword), type);
}
case SyntaxKind.IdentifierName:
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(NonNullTypesContext,
BindNonGenericSimpleNamespaceOrTypeOrAliasSymbol((IdentifierNameSyntax)syntax, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics, qualifierOpt: null));
return BindNonGenericSimpleNamespaceOrTypeOrAliasSymbol((IdentifierNameSyntax)syntax, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics, qualifierOpt: null);
case SyntaxKind.GenericName:
return TypeSymbolWithAnnotations.Create(NonNullTypesContext,
BindGenericSimpleNamespaceOrTypeOrAliasSymbol((GenericNameSyntax)syntax, diagnostics, basesBeingResolved, qualifierOpt: null));
return BindGenericSimpleNamespaceOrTypeOrAliasSymbol((GenericNameSyntax)syntax, diagnostics, basesBeingResolved, qualifierOpt: null);
case SyntaxKind.AliasQualifiedName:
{
......@@ -396,19 +391,19 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS
return TypeSymbolWithAnnotations.Create(new ExtendedErrorTypeSymbol(left, LookupResultKind.NotATypeOrNamespace, diagnostics.Add(ErrorCode.ERR_ColColWithTypeAlias, node.Alias.Location, node.Alias.Identifier.Text)));
}
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(NonNullTypesContext, this.BindSimpleNamespaceOrTypeOrAliasSymbol(node.Name, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics, left));
return this.BindSimpleNamespaceOrTypeOrAliasSymbol(node.Name, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics, left);
}
case SyntaxKind.QualifiedName:
{
var node = (QualifiedNameSyntax)syntax;
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(NonNullTypesContext, BindQualifiedName(node.Left, node.Right, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics));
return BindQualifiedName(node.Left, node.Right, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics);
}
case SyntaxKind.SimpleMemberAccessExpression:
{
var node = (MemberAccessExpressionSyntax)syntax;
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(NonNullTypesContext, BindQualifiedName(node.Expression, node.Name, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics));
return BindQualifiedName(node.Expression, node.Name, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics);
}
case SyntaxKind.ArrayType:
......@@ -446,7 +441,7 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS
}
else
{
type = TypeSymbolWithAnnotations.Create(NonNullTypesContext, array);
type = TypeSymbolWithAnnotations.Create(IsNullableEnabled(a.CloseBracketToken), array);
}
}
......@@ -481,7 +476,8 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS
case SyntaxKind.TupleType:
{
return TypeSymbolWithAnnotations.Create(NonNullTypesContext, BindTupleType((TupleTypeSyntax)syntax, diagnostics));
var tupleTypeSyntax = (TupleTypeSyntax)syntax;
return TypeSymbolWithAnnotations.Create(IsNullableEnabled(tupleTypeSyntax.CloseParenToken), BindTupleType(tupleTypeSyntax, diagnostics));
}
case SyntaxKind.RefType:
......@@ -503,15 +499,16 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS
void reportNullableReferenceTypesIfNeeded(SyntaxToken questionToken, TypeSymbolWithAnnotations typeArgument = default)
{
// Inside a method body or other executable code, we can pull on NonNullTypes symbol or question IsValueType without causing cycles.
// We still need to delay that check when binding in an attribute argument
if (!InExecutableBinder || !ShouldCheckConstraintsNullability)
bool isNullableEnabled = IsNullableEnabled(questionToken);
// Inside a method body or other executable code, we can question IsValueType without causing cycles.
if (!typeArgument.IsNull && !ShouldCheckConstraints)
{
diagnostics.Add(new LazyMissingNonNullTypesContextDiagnosticInfo(Compilation, NonNullTypesContext, typeArgument), questionToken.GetLocation());
diagnostics.Add(new LazyMissingNonNullTypesContextDiagnosticInfo(Compilation, isNullableEnabled, typeArgument), questionToken.GetLocation());
}
else
{
DiagnosticInfo info = LazyMissingNonNullTypesContextDiagnosticInfo.ReportNullableReferenceTypesIfNeeded(Compilation, NonNullTypesContext, typeArgument);
DiagnosticInfo info = LazyMissingNonNullTypesContextDiagnosticInfo.ReportNullableReferenceTypesIfNeeded(Compilation, isNullableEnabled, typeArgument);
if (!(info is null))
{
......@@ -651,7 +648,7 @@ private NamedTypeSymbol BindPredefinedTypeSymbol(PredefinedTypeSyntax node, Diag
/// <summary>
/// Binds a simple name or the simple name portion of a qualified name.
/// </summary>
private Symbol BindSimpleNamespaceOrTypeOrAliasSymbol(
private NamespaceOrTypeOrAliasSymbolWithAnnotations BindSimpleNamespaceOrTypeOrAliasSymbol(
SimpleNameSyntax syntax,
DiagnosticBag diagnostics,
ConsList<Symbol> basesBeingResolved,
......@@ -668,7 +665,7 @@ private NamedTypeSymbol BindPredefinedTypeSymbol(PredefinedTypeSyntax node, Diag
switch (syntax.Kind())
{
default:
return new ExtendedErrorTypeSymbol(qualifierOpt ?? this.Compilation.Assembly.GlobalNamespace, string.Empty, arity: 0, errorInfo: null);
return TypeSymbolWithAnnotations.Create(new ExtendedErrorTypeSymbol(qualifierOpt ?? this.Compilation.Assembly.GlobalNamespace, string.Empty, arity: 0, errorInfo: null));
case SyntaxKind.IdentifierName:
return BindNonGenericSimpleNamespaceOrTypeOrAliasSymbol((IdentifierNameSyntax)syntax, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics, qualifierOpt);
......@@ -701,7 +698,7 @@ private static bool IsViableType(LookupResult result)
return false;
}
protected Symbol BindNonGenericSimpleNamespaceOrTypeOrAliasSymbol(
protected NamespaceOrTypeOrAliasSymbolWithAnnotations BindNonGenericSimpleNamespaceOrTypeOrAliasSymbol(
IdentifierNameSyntax node,
DiagnosticBag diagnostics,
ConsList<Symbol> basesBeingResolved,
......@@ -717,15 +714,15 @@ private static bool IsViableType(LookupResult result)
if (string.IsNullOrWhiteSpace(identifierValueText))
{
return new ExtendedErrorTypeSymbol(
return TypeSymbolWithAnnotations.Create(new ExtendedErrorTypeSymbol(
Compilation.Assembly.GlobalNamespace, identifierValueText, 0,
new CSDiagnosticInfo(ErrorCode.ERR_SingleTypeNameNotFound));
new CSDiagnosticInfo(ErrorCode.ERR_SingleTypeNameNotFound)));
}
var errorResult = CreateErrorIfLookupOnTypeParameter(node.Parent, qualifierOpt, identifierValueText, 0, diagnostics);
if ((object)errorResult != null)
{
return errorResult;
return TypeSymbolWithAnnotations.Create(errorResult);
}
var result = LookupResult.GetInstance();
......@@ -765,7 +762,7 @@ private static bool IsViableType(LookupResult result)
}
result.Free();
return bindingResult;
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(IsNullableEnabled(node.Identifier), bindingResult);
}
private void ReportUseSiteDiagnosticForDynamic(DiagnosticBag diagnostics, IdentifierNameSyntax node)
......@@ -834,7 +831,7 @@ private NamespaceOrTypeOrAliasSymbolWithAnnotations UnwrapAlias(NamespaceOrTypeO
if (symbol.IsAlias)
{
AliasSymbol discarded;
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(NonNullTypesContext, (NamespaceOrTypeSymbol)UnwrapAlias(symbol.Symbol, out discarded, diagnostics, syntax, basesBeingResolved));
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(symbol.IsNullableEnabled, (NamespaceOrTypeSymbol)UnwrapAlias(symbol.Symbol, out discarded, diagnostics, syntax, basesBeingResolved));
}
return symbol;
......@@ -844,7 +841,7 @@ private NamespaceOrTypeOrAliasSymbolWithAnnotations UnwrapAlias(NamespaceOrTypeO
{
if (symbol.IsAlias)
{
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(NonNullTypesContext, (NamespaceOrTypeSymbol)UnwrapAlias(symbol.Symbol, out alias, diagnostics, syntax, basesBeingResolved));
return NamespaceOrTypeOrAliasSymbolWithAnnotations.CreateUnannotated(symbol.IsNullableEnabled, (NamespaceOrTypeSymbol)UnwrapAlias(symbol.Symbol, out alias, diagnostics, syntax, basesBeingResolved));
}
alias = null;
......@@ -885,7 +882,7 @@ private Symbol UnwrapAlias(Symbol symbol, out AliasSymbol alias, DiagnosticBag d
return symbol;
}
private NamedTypeSymbol BindGenericSimpleNamespaceOrTypeOrAliasSymbol(
private TypeSymbolWithAnnotations BindGenericSimpleNamespaceOrTypeOrAliasSymbol(
GenericNameSyntax node,
DiagnosticBag diagnostics,
ConsList<Symbol> basesBeingResolved,
......@@ -995,7 +992,7 @@ private Symbol UnwrapAlias(Symbol symbol, out AliasSymbol alias, DiagnosticBag d
LookupResultKind.NotAnAttributeType, errorInfo: null);
}
return resultType;
return TypeSymbolWithAnnotations.Create(IsNullableEnabled(node.TypeArgumentList.GreaterThanToken), resultType);
}
private NamedTypeSymbol LookupGenericTypeName(
......@@ -1194,11 +1191,6 @@ private NamedTypeSymbol ConstructNamedTypeUnlessTypeArgumentOmitted(SyntaxNode t
{
bool includeNullability = Compilation.IsFeatureEnabled(MessageID.IDS_FeatureNullableReferenceTypes);
var conversions = this.Conversions.WithNullability(includeNullability);
if (includeNullability && !ShouldCheckConstraintsNullability)
{
diagnostics.Add(new LazyNullableContraintChecksDiagnosticInfo(type, conversions, this.Compilation), typeSyntax.GetLocation());
conversions = this.Conversions.WithNullability(includeNullability: false);
}
type.CheckConstraintsForNonTuple(conversions, typeSyntax, typeArgumentsSyntax, this.Compilation, basesBeingResolved, diagnostics);
}
......@@ -1219,15 +1211,7 @@ private bool ShouldCheckConstraints
}
}
private bool ShouldCheckConstraintsNullability
{
get
{
return ShouldCheckConstraints && !this.Flags.Includes(BinderFlags.AttributeArgument);
}
}
private NamespaceOrTypeSymbol BindQualifiedName(
private NamespaceOrTypeOrAliasSymbolWithAnnotations BindQualifiedName(
ExpressionSyntax leftName,
SimpleNameSyntax rightName,
DiagnosticBag diagnostics,
......@@ -1249,17 +1233,18 @@ private bool ShouldCheckConstraintsNullability
}
// since the name is qualified, it cannot result in a using alias symbol, only a type or namespace
var right = this.BindSimpleNamespaceOrTypeOrAliasSymbol(rightName, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics, left) as NamespaceOrTypeSymbol;
var right = this.BindSimpleNamespaceOrTypeOrAliasSymbol(rightName, diagnostics, basesBeingResolved, suppressUseSiteDiagnostics, left);
// If left name bound to an unbound generic type
// and right name bound to a generic type, we must
// convert right to an unbound generic type.
if (isLeftUnboundGenericType)
{
var namedTypeRight = right as NamedTypeSymbol;
var namedTypeRight = right.Symbol as NamedTypeSymbol;
if ((object)namedTypeRight != null && namedTypeRight.IsGenericType)
{
right = namedTypeRight.AsUnboundGenericType();
TypeSymbolWithAnnotations type = right.Type;
right = type.WithTypeAndModifiers(namedTypeRight.AsUnboundGenericType(), type.CustomModifiers);
}
}
......
......@@ -411,7 +411,7 @@ private static (ImmutableArray<BoundExpression> Elements, ImmutableArray<string>
ImmutableArray<Location> elementLocations = elements.SelectAsArray(e => e.Syntax.Location);
var tuple = TupleTypeSymbol.Create(locationOpt: null,
elementTypes: convertedTypes.SelectAsArray((t, m) => TypeSymbolWithAnnotations.Create(nonNullTypesContext: m, t), compilation.SourceModule),
elementTypes: convertedTypes.SelectAsArray(t => TypeSymbolWithAnnotations.Create(t)),
elementLocations, elementNames: names, compilation,
shouldCheckConstraints: true, errorPositions: default, syntax, diagnostics);
......
......@@ -157,6 +157,11 @@ internal override Symbol ContainingMemberOrLambda
}
}
internal override bool IsNullableGloballyEnabled()
{
return Compilation.Options.Nullable;
}
internal override Binder GetBinder(SyntaxNode node)
{
return null;
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
{
/// <summary>
/// Instead of storing a bool to tell us if we're in a NonNullTypes context,
/// we use this interface to pull on that information lazily.
/// </summary>
internal interface INonNullTypesContext
{
bool? NonNullTypes { get; }
}
internal sealed class NonNullTypesTrueContext : INonNullTypesContext
{
public static readonly INonNullTypesContext Instance = new NonNullTypesTrueContext();
public bool? NonNullTypes => true;
}
internal sealed class NonNullTypesNullContext : INonNullTypesContext
{
public static readonly INonNullTypesContext Instance = new NonNullTypesNullContext();
public bool? NonNullTypes => null;
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed class WithNullableContextBinder : Binder
{
private readonly SyntaxTree _syntaxTree;
private readonly int _position;
internal WithNullableContextBinder(SyntaxTree syntaxTree, int position, Binder next)
: base(next)
{
Debug.Assert(syntaxTree != null);
Debug.Assert(position >= 0);
_syntaxTree = syntaxTree;
_position = position;
}
internal override bool IsNullableGloballyEnabled()
{
return Next.IsNullableEnabled(_syntaxTree, _position);
}
}
}
......@@ -20,7 +20,7 @@ public BoundDeconstructValuePlaceholder SetInferredType(TypeSymbolWithAnnotation
public BoundDeconstructValuePlaceholder FailInference(Binder binder)
{
return SetInferredType(TypeSymbolWithAnnotations.Create(binder.NonNullTypesContext, binder.CreateErrorType()), binder, success: false);
return SetInferredType(TypeSymbolWithAnnotations.Create(binder.CreateErrorType()), binder, success: false);
}
}
}
......@@ -604,7 +604,7 @@ private BoundLambda ReallyInferReturnType(NamedTypeSymbol delegateType, Immutabl
var returnType = inferredReturnType.Type;
if (returnType.IsNull)
{
returnType = TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, LambdaSymbol.InferenceFailureReturnType);
returnType = TypeSymbolWithAnnotations.Create(LambdaSymbol.InferenceFailureReturnType);
}
lambdaSymbol.SetInferredReturnType(inferredReturnType.RefKind, returnType);
......
......@@ -38,7 +38,7 @@ internal BoundExpression SetInferredType(TypeSymbolWithAnnotations type, Binder
if (inferenceFailed)
{
type = TypeSymbolWithAnnotations.Create(binderOpt.NonNullTypesContext, binderOpt.CreateErrorType("var"));
type = TypeSymbolWithAnnotations.Create(binderOpt.CreateErrorType("var"));
}
switch (this.VariableSymbol.Kind)
......
......@@ -215,6 +215,8 @@ internal Binder GetSpeculativeBinder(int position, ExpressionSyntax expression,
binder = new TypeofBinder(expression, binder);
}
binder = new WithNullableContextBinder(SyntaxTree, position, binder);
return new ExecutableCodeBinder(expression, binder.ContainingMemberOrLambda, binder).GetBinder(expression);
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
namespace Microsoft.CodeAnalysis.CSharp
......@@ -10,19 +11,20 @@ namespace Microsoft.CodeAnalysis.CSharp
internal sealed class LazyMissingNonNullTypesContextDiagnosticInfo : LazyDiagnosticInfo
{
private readonly CSharpCompilation _compilation;
private readonly INonNullTypesContext _context;
private readonly bool _isNullableEnabled;
private readonly TypeSymbolWithAnnotations _type;
internal LazyMissingNonNullTypesContextDiagnosticInfo(CSharpCompilation compilation, INonNullTypesContext context, TypeSymbolWithAnnotations type)
internal LazyMissingNonNullTypesContextDiagnosticInfo(CSharpCompilation compilation, bool isNullableEnabled, TypeSymbolWithAnnotations type)
{
Debug.Assert(!type.IsNull);
_compilation = compilation;
_context = context;
_isNullableEnabled = isNullableEnabled;
_type = type;
}
protected override DiagnosticInfo ResolveInfo()
{
return ReportNullableReferenceTypesIfNeeded(_compilation, _context, _type);
return ReportNullableReferenceTypesIfNeeded(_compilation, _isNullableEnabled, _type);
}
/// <summary>
......@@ -30,12 +32,12 @@ protected override DiagnosticInfo ResolveInfo()
/// - an error before C# 8.0
/// - a warning outside of a NonNullTypes context
/// </summary>
public static DiagnosticInfo ReportNullableReferenceTypesIfNeeded(CSharpCompilation compilation, INonNullTypesContext context, TypeSymbolWithAnnotations type)
public static DiagnosticInfo ReportNullableReferenceTypesIfNeeded(CSharpCompilation compilation, bool isNullableEnabled, TypeSymbolWithAnnotations type)
{
return !type.IsNull && (type.IsValueType || type.IsErrorType()) ? null : ReportNullableReferenceTypesIfNeeded(compilation, context);
return !type.IsNull && (type.IsValueType || type.IsErrorType()) ? null : ReportNullableReferenceTypesIfNeeded(compilation, isNullableEnabled);
}
private static DiagnosticInfo ReportNullableReferenceTypesIfNeeded(CSharpCompilation compilation, INonNullTypesContext nonNullTypesContext)
public static DiagnosticInfo ReportNullableReferenceTypesIfNeeded(CSharpCompilation compilation, bool isNullableEnabled)
{
var featureID = MessageID.IDS_FeatureNullableReferenceTypes;
if (!compilation.IsFeatureEnabled(featureID))
......@@ -45,7 +47,7 @@ private static DiagnosticInfo ReportNullableReferenceTypesIfNeeded(CSharpCompila
return new CSDiagnosticInfo(availableVersion.GetErrorCode(), featureID.Localize(), new CSharpRequiredLanguageVersion(requiredVersion));
}
else if (nonNullTypesContext.NonNullTypes != true)
else if (!isNullableEnabled)
{
return new CSDiagnosticInfo(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation);
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.Symbols;
namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed class LazyNullAsNonNullableDiagnosticInfo : LazyDiagnosticInfo
{
private readonly TypeSymbolWithAnnotations _possiblyNullableType;
internal LazyNullAsNonNullableDiagnosticInfo(TypeSymbolWithAnnotations possiblyNullableType)
{
_possiblyNullableType = possiblyNullableType;
}
protected override DiagnosticInfo ResolveInfo()
{
if (_possiblyNullableType.NullableAnnotation.IsAnyNotNullable())
{
return new CSDiagnosticInfo(ErrorCode.WRN_NullAsNonNullable);
}
return null;
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis.CSharp
{
/// <summary>
/// A lazily calculated diagnostic for constraint check nullability.
/// </summary>
internal sealed class LazyNullableContraintChecksDiagnosticInfo : LazyDiagnosticInfo
{
private readonly NamedTypeSymbol _type;
private readonly ConversionsBase _conversions;
private readonly Compilation _compilation;
internal LazyNullableContraintChecksDiagnosticInfo(NamedTypeSymbol type, ConversionsBase conversions, Compilation compilation)
{
_type = type;
_conversions = conversions;
_compilation = compilation;
}
protected override DiagnosticInfo ResolveInfo()
{
var diagnosticsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
var warningsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
// CheckTypeConstraints should only add nullability warnings to warningsBuilder.
ConstraintsHelper.CheckTypeConstraints(
_type,
_conversions,
_compilation,
diagnosticsBuilder,
warningsBuilder,
ref useSiteDiagnosticsBuilder);
// If there are multiple constraint check warnings, we'll report the first one only.
var diagnostic = (warningsBuilder.Count == 0) ? null : warningsBuilder[0].DiagnosticInfo;
useSiteDiagnosticsBuilder?.Free();
warningsBuilder.Free();
diagnosticsBuilder.Free();
return diagnostic;
}
}
}
......@@ -786,10 +786,22 @@ private void AddTypeParameterConstraints(ImmutableArray<ITypeSymbol> typeArgumen
if (typeParam.HasReferenceTypeConstraint)
{
AddKeyword(SyntaxKind.ClassKeyword);
if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier) &&
typeParameterSymbol?.ReferenceTypeConstraintIsNullable == true) // https://github.com/dotnet/roslyn/issues/26198 Switch to public API when we will have one.
switch (typeParameterSymbol?.ReferenceTypeConstraintIsNullable) // https://github.com/dotnet/roslyn/issues/26198 Switch to public API when we will have one.
{
AddPunctuation(SyntaxKind.QuestionToken);
case true:
if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier))
{
AddPunctuation(SyntaxKind.QuestionToken);
}
break;
case false:
if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier))
{
AddPunctuation(SyntaxKind.ExclamationToken);
}
break;
}
needComma = true;
......
......@@ -591,8 +591,6 @@ public override int GetHashCode()
}
return _hashCode;
}
public override bool? NonNullTypes => false;
}
internal sealed class ConstructedErrorTypeSymbol : SubstitutedErrorTypeSymbol
......
......@@ -91,15 +91,6 @@ internal bool HasAssociatedField
/// </summary>
internal abstract bool HasSpecialName { get; }
public override bool? NonNullTypes
{
get
{
Debug.Assert(IsDefinition);
return ContainingType?.NonNullTypes;
}
}
/// <summary>
/// Gets the attributes on event's associated field, if any.
/// Returns an empty <see cref="ImmutableArray&lt;AttributeData&gt;"/> if
......
......@@ -157,15 +157,6 @@ public virtual object ConstantValue
internal abstract ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes);
public override bool? NonNullTypes
{
get
{
Debug.Assert(IsDefinition);
return (AssociatedSymbol ?? ContainingType)?.NonNullTypes;
}
}
/// <summary>
/// Gets the kind of this symbol.
/// </summary>
......
......@@ -155,14 +155,6 @@ public sealed override Accessibility DeclaredAccessibility
}
}
public override bool? NonNullTypes
{
get
{
throw ExceptionUtilities.Unreachable;
}
}
/// <summary>
/// Returns value 'Local' of the <see cref="SymbolKind"/>
/// </summary>
......
......@@ -473,13 +473,5 @@ internal override ObsoleteAttributeData ObsoleteAttributeData
{
get { return null; }
}
public override bool? NonNullTypes
{
get
{
throw ExceptionUtilities.Unreachable;
}
}
}
}
......@@ -506,13 +506,5 @@ internal override ObsoleteAttributeData ObsoleteAttributeData
{
get { return null; }
}
public override bool? NonNullTypes
{
get
{
throw ExceptionUtilities.Unreachable;
}
}
}
}
......@@ -711,14 +711,6 @@ public override bool IsExtensionMethod
}
}
public override bool? NonNullTypes
{
get
{
throw ExceptionUtilities.Unreachable;
}
}
public override ImmutableArray<Location> Locations => _containingType.ContainingPEModule.MetadataLocation.Cast<MetadataLocation, Location>();
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences => ImmutableArray<SyntaxReference>.Empty;
......
......@@ -696,13 +696,5 @@ internal IEnumerable<NamedTypeSymbol> GetForwardedTypes()
}
public override ModuleMetadata GetMetadata() => _module.GetNonDisposableMetadata();
public override bool? NonNullTypes
{
get
{
throw ExceptionUtilities.Unreachable;
}
}
}
}
......@@ -1986,14 +1986,6 @@ internal string DefaultMemberName
}
}
public override bool? NonNullTypes
{
get
{
throw ExceptionUtilities.Unreachable;
}
}
internal override bool IsComImport
{
get
......
......@@ -735,14 +735,6 @@ internal override bool HasRuntimeSpecialName
get { return null; }
}
public override bool? NonNullTypes
{
get
{
throw ExceptionUtilities.Unreachable;
}
}
private sealed class PEPropertySymbolWithCustomModifiers : PEPropertySymbol
{
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
......
......@@ -172,9 +172,8 @@ internal override TypeSymbol MakeUnboundIfGeneric(PEModuleSymbol moduleSymbol, T
private static TypeSymbolWithAnnotations CreateType(TypeSymbol type, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers)
{
// NonNullTypesContext is unset because the actual context will
// be set when these types are transformed by the caller.
return TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, type, customModifiers: CSharpCustomModifier.Convert(customModifiers));
// The actual annotation will be set when these types are transformed by the caller.
return TypeSymbolWithAnnotations.Create(type, NullableAnnotation.Unknown, CSharpCustomModifier.Convert(customModifiers));
}
}
}
......@@ -954,14 +954,6 @@ internal virtual bool SynthesizesLoweredBoundBody
/// </remarks>
internal abstract int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree);
public override bool? NonNullTypes
{
get
{
return (AssociatedSymbol ?? ContainingSymbol)?.NonNullTypes;
}
}
#region IMethodSymbol Members
MethodKind IMethodSymbol.MethodKind
......
......@@ -185,8 +185,6 @@ internal override bool HasAssemblyRuntimeCompatibilityAttribute
}
public override ModuleMetadata GetMetadata() => null;
public override bool? NonNullTypes => false;
}
internal sealed class MissingModuleSymbolWithName : MissingModuleSymbol
......
......@@ -962,30 +962,19 @@ private static VarianceKind GetTypeArgumentVariance(VarianceKind typeVariance, V
/// parameters in the type.</param>
public NamedTypeSymbol Construct(params TypeSymbol[] typeArguments)
{
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass an explicit context.
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false, NonNullTypesNullContext.Instance);
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass TypeSymbolWithAnnotations[] instead of TypeSymbol[].
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false);
}
/// <summary>
/// Returns a constructed type given its type arguments.
/// </summary>
/// <param name="nonNullTypesContext">This context indicates how to interpret un-annotated types.</param>
/// <param name="typeArguments">The immediate type arguments to be replaced for type
/// parameters in the type.</param>
public NamedTypeSymbol Construct(INonNullTypesContext nonNullTypesContext, params TypeSymbol[] typeArguments)
public NamedTypeSymbol Construct(ImmutableArray<TypeSymbol> typeArguments)
{
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false, nonNullTypesContext);
}
/// <summary>
/// Returns a constructed type given its type arguments.
/// </summary>
/// <param name="typeArguments">The immediate type arguments to be replaced for type
/// parameters in the type.</param>
public NamedTypeSymbol Construct(ImmutableArray<TypeSymbol> typeArguments, INonNullTypesContext nonNullTypesContext = null)
{
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass an explicit context.
return ConstructWithoutModifiers(typeArguments, false, nonNullTypesContext ?? NonNullTypesNullContext.Instance);
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass ImmutableArray<TypeSymbolWithAnnotations> instead of ImmutableArray<TypeSymbol>.
return ConstructWithoutModifiers(typeArguments, false);
}
/// <summary>
......@@ -994,8 +983,8 @@ public NamedTypeSymbol Construct(ImmutableArray<TypeSymbol> typeArguments, INonN
/// <param name="typeArguments"></param>
public NamedTypeSymbol Construct(IEnumerable<TypeSymbol> typeArguments)
{
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass an explicit context.
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false, NonNullTypesNullContext.Instance);
// https://github.com/dotnet/roslyn/issues/30064: We should fix the callers to pass IEnumerable<TypeSymbolWithAnnotations> instead of IEnumerable<TypeSymbol>.
return ConstructWithoutModifiers(typeArguments.AsImmutableOrNull(), false);
}
/// <summary>
......@@ -1025,7 +1014,7 @@ internal NamedTypeSymbol GetUnboundGenericTypeOrSelf()
internal static readonly Func<TypeSymbolWithAnnotations, bool> TypeSymbolIsErrorType = type => !type.IsNull && type.IsErrorType();
private NamedTypeSymbol ConstructWithoutModifiers(ImmutableArray<TypeSymbol> typeArguments, bool unbound, INonNullTypesContext nonNullTypesContext)
private NamedTypeSymbol ConstructWithoutModifiers(ImmutableArray<TypeSymbol> typeArguments, bool unbound)
{
ImmutableArray<TypeSymbolWithAnnotations> modifiedArguments;
......@@ -1035,7 +1024,7 @@ private NamedTypeSymbol ConstructWithoutModifiers(ImmutableArray<TypeSymbol> typ
}
else
{
modifiedArguments = typeArguments.SelectAsArray((t, c) => t == null ? default : TypeSymbolWithAnnotations.Create(c, t), nonNullTypesContext);
modifiedArguments = typeArguments.SelectAsArray(t => TypeSymbolWithAnnotations.Create(t));
}
return Construct(modifiedArguments, unbound);
......@@ -1406,15 +1395,6 @@ protected CharSet DefaultMarshallingCharSet
}
}
public override bool? NonNullTypes
{
get
{
Debug.Assert(IsDefinition);
return ((Symbol)ContainingType ?? base.ContainingModule)?.NonNullTypes;
}
}
/// <summary>
/// Marshalling charset of string data fields within the type (string formatting flags in metadata).
/// </summary>
......
......@@ -230,15 +230,6 @@ public object ExplicitDefaultValue
/// </remarks>
internal abstract ConstantValue ExplicitDefaultConstantValue { get; }
public override bool? NonNullTypes
{
get
{
Debug.Assert(IsDefinition);
return ContainingSymbol?.NonNullTypes;
}
}
/// <summary>
/// Gets the kind of this symbol.
/// </summary>
......
......@@ -169,15 +169,6 @@ public bool IsWriteOnly
/// </summary>
internal abstract bool HasSpecialName { get; }
public override bool? NonNullTypes
{
get
{
Debug.Assert(IsDefinition);
return ContainingType?.NonNullTypes;
}
}
/// <summary>
/// The 'get' accessor of the property, or null if the property is write-only.
/// </summary>
......
......@@ -185,13 +185,5 @@ internal override DiagnosticInfo GetUseSiteDiagnostic()
{
get { return null; }
}
public override bool? NonNullTypes
{
get
{
return _underlyingEvent.NonNullTypes;
}
}
}
}
......@@ -125,13 +125,5 @@ internal override DiagnosticInfo GetUseSiteDiagnostic()
{
get { return null; }
}
public override bool? NonNullTypes
{
get
{
return _underlyingField.NonNullTypes;
}
}
}
}
......@@ -310,13 +310,5 @@ internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree l
// retargeting symbols refer to a symbol from another compilation, they don't define locals in the current compilation
throw ExceptionUtilities.Unreachable;
}
public override bool? NonNullTypes
{
get
{
return _underlyingMethod.NonNullTypes;
}
}
}
}
......@@ -285,13 +285,5 @@ internal override bool HasAssemblyRuntimeCompatibilityAttribute
}
public override ModuleMetadata GetMetadata() => _underlyingModule.GetMetadata();
public override bool? NonNullTypes
{
get
{
return _underlyingModule.NonNullTypes;
}
}
}
}
......@@ -357,13 +357,5 @@ internal override bool IsComImport
{
get { return null; }
}
public override bool? NonNullTypes
{
get
{
return _underlyingType.NonNullTypes;
}
}
}
}
......@@ -242,13 +242,5 @@ internal override DiagnosticInfo GetUseSiteDiagnostic()
{
get { return null; }
}
public override bool? NonNullTypes
{
get
{
return _underlyingProperty.NonNullTypes;
}
}
}
}
......@@ -77,8 +77,6 @@ internal sealed class SignatureOnlyMethodSymbol : MethodSymbol
public override string Name { get { return _name; } }
public override bool? NonNullTypes => false;
#region Not used by MethodSignatureComparer
internal override bool GenerateDebugInfo { get { throw ExceptionUtilities.Unreachable; } }
......
......@@ -336,14 +336,6 @@ internal sealed override bool HasSpecialName
}
}
public sealed override bool? NonNullTypes
{
get
{
return GetNonNullTypesFromSyntax() ?? (AssociatedSymbol ?? ContainingModule)?.NonNullTypes;
}
}
internal sealed override bool IsNotSerialized
{
get
......
......@@ -91,7 +91,7 @@ internal override TypeSymbolWithAnnotations GetFieldType(ConsList<FieldSymbol> f
if (isVar)
{
diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this);
type = TypeSymbolWithAnnotations.Create(binder.NonNullTypesContext, binder.CreateErrorType("var"));
type = TypeSymbolWithAnnotations.Create(binder.CreateErrorType("var"));
}
SetType(compilation, diagnostics, type);
......
......@@ -47,7 +47,7 @@ internal sealed class LambdaSymbol : SourceMethodSymbol
_messageID = unboundLambda.Data.MessageID;
_syntax = unboundLambda.Syntax;
_refKind = refKind;
_returnType = returnType.IsNull ? TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, ReturnTypeIsBeingInferred) : returnType;
_returnType = returnType.IsNull ? TypeSymbolWithAnnotations.Create(ReturnTypeIsBeingInferred) : returnType;
_isSynthesized = unboundLambda.WasCompilerGenerated;
_isAsync = unboundLambda.IsAsync;
// No point in making this lazy. We are always going to need these soon after creation of the symbol.
......
......@@ -871,14 +871,6 @@ internal SourceModuleSymbol SourceModule
get { return (SourceModuleSymbol)this.Modules[0]; }
}
public override bool? NonNullTypes
{
get
{
return SourceModule.NonNullTypes;
}
}
internal override bool RequiresCompletion
{
get { return true; }
......
......@@ -235,12 +235,12 @@ protected ConstantValue MakeDefaultExpression(DiagnosticBag diagnostics, Binder
}
if (parameterType.IsReferenceType &&
parameterType.NullableAnnotation.IsAnyNotNullable() &&
convertedExpression.ConstantValue?.IsNull == true &&
!suppressNullableWarning(convertedExpression) &&
DeclaringCompilation.LanguageVersion >= MessageID.IDS_FeatureNullableReferenceTypes.RequiredVersion())
{
// Note: Eagerly calling IsNullable causes a cycle, so we delay the check
diagnostics.Add(new LazyNullAsNonNullableDiagnosticInfo(parameterType), parameterSyntax.Default.Value.Location);
diagnostics.Add(ErrorCode.WRN_NullAsNonNullable, parameterSyntax.Default.Value.Location);
}
// represent default(struct) by a Null constant:
......
......@@ -93,7 +93,7 @@ protected override void MethodChecks(DiagnosticBag diagnostics)
diagnostics: diagnostics);
_lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
_lazyReturnType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax));
_lazyReturnType = TypeSymbolWithAnnotations.Create(bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax));
var location = this.Locations[0];
if (MethodKind == MethodKind.StaticConstructor && (_lazyParameters.Length != 0))
......
......@@ -50,8 +50,8 @@ protected void InitializeParameters(ImmutableArray<ParameterSymbol> parameters)
// reuse types to avoid reporting duplicate errors if missing:
var voidType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax));
// https://github.com/dotnet/roslyn/issues/30079: Should the 'object' parameter be considered nullable?
var objectType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: delegateType, binder.GetSpecialType(SpecialType.System_Object, diagnostics, syntax));
// https://github.com/dotnet/roslyn/issues/30079: Should the 'object', IAsyncResult and AsyncCallback parameters be considered nullable or not nullable?
var objectType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Object, diagnostics, syntax));
var intPtrType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_IntPtr, diagnostics, syntax));
if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true))
......@@ -74,8 +74,8 @@ protected void InitializeParameters(ImmutableArray<ParameterSymbol> parameters)
// WinRT delegates don't have Begin/EndInvoke methods
!delegateType.IsCompilationOutputWinMdObj())
{
var iAsyncResultType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: delegateType, binder.GetSpecialType(SpecialType.System_IAsyncResult, diagnostics, syntax));
var asyncCallbackType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: delegateType, binder.GetSpecialType(SpecialType.System_AsyncCallback, diagnostics, syntax));
var iAsyncResultType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_IAsyncResult, diagnostics, syntax));
var asyncCallbackType = TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_AsyncCallback, diagnostics, syntax));
// (3) BeginInvoke
symbols.Add(new BeginInvokeMethod(invoke, iAsyncResultType, objectType, asyncCallbackType, syntax));
......
......@@ -64,7 +64,7 @@ protected sealed override void MethodChecks(DiagnosticBag diagnostics)
// EventRegistrationToken add_E(EventDelegate d);
// Leave the returns void bit in this.flags false.
_lazyReturnType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, eventTokenType);
_lazyReturnType = TypeSymbolWithAnnotations.Create(eventTokenType);
var parameter = new SynthesizedAccessorValueParameterSymbol(this, _event.Type, 0);
_lazyParameters = ImmutableArray.Create<ParameterSymbol>(parameter);
......@@ -77,10 +77,10 @@ protected sealed override void MethodChecks(DiagnosticBag diagnostics)
TypeSymbol voidType = compilation.GetSpecialType(SpecialType.System_Void);
Binder.ReportUseSiteDiagnostics(voidType, diagnostics, this.Location);
_lazyReturnType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, voidType);
_lazyReturnType = TypeSymbolWithAnnotations.Create(voidType);
this.SetReturnsVoid(returnsVoid: true);
var parameter = new SynthesizedAccessorValueParameterSymbol(this, TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, eventTokenType), 0);
var parameter = new SynthesizedAccessorValueParameterSymbol(this, TypeSymbolWithAnnotations.Create(eventTokenType), 0);
_lazyParameters = ImmutableArray.Create<ParameterSymbol>(parameter);
}
}
......@@ -91,7 +91,7 @@ protected sealed override void MethodChecks(DiagnosticBag diagnostics)
TypeSymbol voidType = compilation.GetSpecialType(SpecialType.System_Void);
Binder.ReportUseSiteDiagnostics(voidType, diagnostics, this.Location);
_lazyReturnType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, voidType);
_lazyReturnType = TypeSymbolWithAnnotations.Create(voidType);
this.SetReturnsVoid(returnsVoid: true);
var parameter = new SynthesizedAccessorValueParameterSymbol(this, _event.Type, 0);
......
......@@ -338,14 +338,6 @@ internal sealed override bool HasSpecialName
}
}
public override bool? NonNullTypes
{
get
{
return GetNonNullTypesFromSyntax() ?? ContainingModule?.NonNullTypes;
}
}
public sealed override bool IsAbstract
{
get { return (_modifiers & DeclarationModifiers.Abstract) != 0; }
......
......@@ -473,7 +473,7 @@ internal sealed override TypeSymbolWithAnnotations GetFieldType(ConsList<FieldSy
{
if ((object)initializerOpt.Type != null && !initializerOpt.Type.IsErrorType())
{
type = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, initializerOpt.Type);
type = TypeSymbolWithAnnotations.Create(initializerOpt.Type);
}
_lazyFieldTypeInferred = 1;
......@@ -482,7 +482,7 @@ internal sealed override TypeSymbolWithAnnotations GetFieldType(ConsList<FieldSy
if (type.IsNull)
{
type = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, binder.CreateErrorType("var"));
type = TypeSymbolWithAnnotations.Create(binder.CreateErrorType("var"));
}
}
}
......
......@@ -181,14 +181,6 @@ internal ImmutableArray<Diagnostic> Diagnostics
get { return _cachedDiagnostics; }
}
public override bool? NonNullTypes
{
get
{
return GetNonNullTypesFromSyntax() ?? (AssociatedSymbol ?? ContainingModule)?.NonNullTypes;
}
}
internal ImmutableArray<Diagnostic> SetDiagnostics(ImmutableArray<Diagnostic> newSet, out bool diagsWritten)
{
//return the diagnostics that were actually saved in the event that there were two threads racing.
......
......@@ -513,14 +513,6 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu
}
}
public override bool? NonNullTypes
{
get
{
return _assemblySymbol.DeclaringCompilation.Options.Nullable;
}
}
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<SynthesizedAttributeData> attributes)
{
base.AddSynthesizedAttributes(moduleBuilder, ref attributes);
......
......@@ -919,14 +919,6 @@ internal override bool HasSpecialName
}
}
public override bool? NonNullTypes
{
get
{
return GetNonNullTypesFromSyntax() ?? ContainingModule?.NonNullTypes;
}
}
internal override bool HasCodeAnalysisEmbeddedAttribute
{
get
......
......@@ -373,7 +373,7 @@ private TypeSymbolWithAnnotations ComputeReturnType(DiagnosticBag diagnostics)
else
{
var binder = GetBinder();
return TypeSymbolWithAnnotations.Create(nonNullTypesContext: _property, binder.GetSpecialType(SpecialType.System_Void, diagnostics, this.GetSyntax()));
return TypeSymbolWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Void, diagnostics, this.GetSyntax()));
}
}
......
......@@ -1524,13 +1524,5 @@ private static BaseParameterListSyntax GetParameterListSyntax(BasePropertyDeclar
{
return (syntax.Kind() == SyntaxKind.IndexerDeclaration) ? ((IndexerDeclarationSyntax)syntax).ParameterList : null;
}
public override bool? NonNullTypes
{
get
{
return GetNonNullTypesFromSyntax() ?? ContainingModule?.NonNullTypes;
}
}
}
}
......@@ -400,14 +400,12 @@ internal override sealed void DecodeWellKnownAttribute(ref DecodeWellKnownAttrib
return false;
}
if ((constraints & TypeParameterConstraintKind.NullableReferenceType) == TypeParameterConstraintKind.NullableReferenceType)
switch (constraints & (TypeParameterConstraintKind.NullableReferenceType | TypeParameterConstraintKind.NotNullableReferenceType))
{
return true;
}
if (NonNullTypes == true)
{
return false;
case TypeParameterConstraintKind.NullableReferenceType:
return true;
case TypeParameterConstraintKind.NotNullableReferenceType:
return false;
}
return null;
......
......@@ -6,6 +6,7 @@
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
......@@ -18,6 +19,7 @@ internal enum TypeParameterConstraintKind
Constructor = 0x04,
Unmanaged = 0x08,
NullableReferenceType = ReferenceType | 0x10,
NotNullableReferenceType = ReferenceType | 0x20,
}
/// <summary>
......@@ -52,6 +54,19 @@ internal sealed class TypeParameterConstraintClause
ImmutableArray<TypeConstraintSyntax> typeConstraintsSyntax,
ImmutableArray<TypeParameterConstraintClause> otherPartialDeclarations)
{
#if DEBUG
switch (constraints & (TypeParameterConstraintKind.NullableReferenceType | TypeParameterConstraintKind.NotNullableReferenceType))
{
case TypeParameterConstraintKind.None:
case TypeParameterConstraintKind.ReferenceType:
case TypeParameterConstraintKind.NullableReferenceType:
case TypeParameterConstraintKind.NotNullableReferenceType:
break;
default:
ExceptionUtilities.UnexpectedValue(constraints); // This call asserts.
break;
}
#endif
this.Constraints = constraints;
this.ConstraintTypes = constraintTypes;
this.TypeConstraintsSyntax = typeConstraintsSyntax;
......
......@@ -358,8 +358,6 @@ internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree l
throw ExceptionUtilities.Unreachable;
}
public sealed override bool? NonNullTypes => false;
private int ComputeHashCode()
{
int code = this.OriginalDefinition.GetHashCode();
......
......@@ -361,7 +361,5 @@ internal override IEnumerable<CSharpAttributeData> GetCustomAttributesToEmit(PEM
{
throw ExceptionUtilities.Unreachable;
}
public sealed override bool? NonNullTypes => false;
}
}
......@@ -23,7 +23,7 @@ namespace Microsoft.CodeAnalysis.CSharp
/// exposed by the compiler.
/// </summary>
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
internal abstract partial class Symbol : ISymbol, IFormattable, INonNullTypesContext
internal abstract partial class Symbol : ISymbol, IFormattable
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Changes to the public interface of this class should remain synchronized with the VB version of Symbol.
......@@ -836,44 +836,6 @@ public virtual bool HasUnsupportedMetadata
}
}
/// <summary>
/// Is module/type/method/field/property/event/parameter definition opted-in/out of treating un-annotated types as non-null.
/// This is determined by the presence of the `[NonNullTypes]` attribute.
/// Returns null if no attribute was set.
/// Not valid to call on non-definitions.
/// </summary>
public virtual bool? NonNullTypes
{
get
{
throw ExceptionUtilities.Unreachable;
}
}
internal bool? GetNonNullTypesFromSyntax()
{
bool? result = null;
foreach (Location location in Locations)
{
SyntaxTree tree = location.SourceTree;
if (tree == null)
{
continue;
}
bool? state = ((CSharpSyntaxTree)tree).GetNullableDirectiveState(location.SourceSpan.Start);
if (state == null)
{
continue;
}
if (state == true)
{
return true;
}
result = false;
}
return result;
}
internal DiagnosticInfo GetUseSiteDiagnosticForSymbolOrContainingType()
{
var info = this.GetUseSiteDiagnostic();
......
......@@ -37,7 +37,7 @@ internal static SynthesizedEntryPointSymbol Create(SynthesizedInteractiveInitial
else
{
var systemVoid = Binder.GetSpecialType(compilation, SpecialType.System_Void, DummySyntax(), diagnostics);
return new ScriptEntryPoint(containingType, TypeSymbolWithAnnotations.Create(nonNullTypesContext: containingType, systemVoid));
return new ScriptEntryPoint(containingType, TypeSymbolWithAnnotations.Create(systemVoid));
}
}
......@@ -349,7 +349,7 @@ internal sealed class AsyncForwardEntryPoint : SynthesizedEntryPointSymbol
public override ImmutableArray<ParameterSymbol> Parameters => _parameters;
public override TypeSymbolWithAnnotations ReturnType => TypeSymbolWithAnnotations.Create(nonNullTypesContext: ContainingModule, _getAwaiterGetResultCall.Type);
public override TypeSymbolWithAnnotations ReturnType => TypeSymbolWithAnnotations.Create(_getAwaiterGetResultCall.Type);
internal override BoundBlock CreateBody(DiagnosticBag diagnostics)
{
......@@ -496,7 +496,7 @@ private sealed class SubmissionEntryPoint : SynthesizedEntryPointSymbol
Debug.Assert(containingType.IsSubmissionClass);
Debug.Assert(returnType.SpecialType != SpecialType.System_Void);
_parameters = ImmutableArray.Create(SynthesizedParameterSymbol.Create(this,
TypeSymbolWithAnnotations.Create(nonNullTypesContext: ContainingModule, submissionArrayType), 0, RefKind.None, "submissionArray"));
TypeSymbolWithAnnotations.Create(submissionArrayType), 0, RefKind.None, "submissionArray"));
_returnType = returnType;
}
......
......@@ -259,7 +259,5 @@ internal override ImmutableArray<string> GetAppliedConditionalSymbols()
{
return ImmutableArray<string>.Empty;
}
public override bool? NonNullTypes => false;
}
}
......@@ -137,7 +137,7 @@ public override bool ReturnsVoid
public override TypeSymbolWithAnnotations ReturnType
{
get { return TypeSymbolWithAnnotations.Create(nonNullTypesContext: ContainingSymbol, _returnType); }
get { return TypeSymbolWithAnnotations.Create(_returnType); }
}
public override ImmutableArray<CustomModifier> RefCustomModifiers
......@@ -251,7 +251,7 @@ internal TypeSymbol ResultType
resultType = (object)submissionReturnTypeOpt == null
? compilation.GetSpecialType(SpecialType.System_Object)
: compilation.GetTypeByReflectionType(submissionReturnTypeOpt, diagnostics);
returnType = taskT.Construct(nonNullTypesContext: containingType, resultType);
returnType = taskT.Construct(resultType);
}
}
}
......@@ -172,8 +172,6 @@ internal override DiagnosticInfo GetUseSiteDiagnostic()
return result;
}
public override bool? NonNullTypes => false;
public override int GetHashCode()
{
return _underlyingMethod.ConstructedFrom.GetHashCode();
......
......@@ -20,9 +20,7 @@ internal sealed class TypeMap : AbstractTypeParameterMap
internal static ImmutableArray<TypeSymbolWithAnnotations> TypeParametersAsTypeSymbolsWithAnnotations(ImmutableArray<TypeParameterSymbol> typeParameters)
{
return typeParameters.SelectAsArray((tp) =>
TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, tp, isAnnotated: false, customModifiers: ImmutableArray<CustomModifier>.Empty)
);
return typeParameters.SelectAsArray((tp) => TypeSymbolWithAnnotations.Create(tp));
}
internal static ImmutableArray<TypeSymbol> AsTypeSymbols(ImmutableArray<TypeSymbolWithAnnotations> typesOpt)
......@@ -119,7 +117,7 @@ private TypeMap WithAlphaRename(ImmutableArray<TypeParameterSymbol> oldTypeParam
var newTp = synthesized ?
new SynthesizedSubstitutedTypeParameterSymbol(newOwner, result, tp, ordinal) :
new SubstitutedTypeParameterSymbol(newOwner, result, tp, ordinal);
result.Mapping.Add(tp, TypeSymbolWithAnnotations.Create(NonNullTypesNullContext.Instance, newTp));
result.Mapping.Add(tp, TypeSymbolWithAnnotations.Create(newTp));
newTypeParametersBuilder.Add(newTp);
ordinal++;
}
......
......@@ -689,14 +689,6 @@ internal override TypeSymbol MergeNullability(TypeSymbol other, VarianceKind var
return this;
}
public override sealed bool? NonNullTypes
{
get
{
return ContainingSymbol.NonNullTypes;
}
}
#region ITypeParameterTypeSymbol Members
TypeParameterKind ITypeParameterSymbol.TypeParameterKind
......
......@@ -338,7 +338,6 @@ private TypeSymbolWithAnnotations(TypeSymbol defaultType, NullableAnnotation nul
public string Name => TypeSymbol.Name;
public SymbolKind Kind => TypeSymbol.Kind;
// Note: We cannot pull on NonNullTypes while debugging, as that causes cycles, so we only display annotated vs. un-annotated.
internal static readonly SymbolDisplayFormat DebuggerDisplayFormat = new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
......@@ -350,19 +349,14 @@ private TypeSymbolWithAnnotations(TypeSymbol defaultType, NullableAnnotation nul
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier,
compilerInternalOptions: SymbolDisplayCompilerInternalOptions.IncludeNonNullableTypeModifier);
internal static TypeSymbolWithAnnotations Create(INonNullTypesContext nonNullTypesContext, TypeSymbol typeSymbol, bool isAnnotated = false, ImmutableArray<CustomModifier> customModifiers = default)
internal static TypeSymbolWithAnnotations Create(bool isNullableEnabled, TypeSymbol typeSymbol, bool isAnnotated = false, ImmutableArray<CustomModifier> customModifiers = default)
{
Debug.Assert(nonNullTypesContext != null);
Debug.Assert((nonNullTypesContext as Symbol)?.IsDefinition != false);
#if DEBUG
_ = nonNullTypesContext.NonNullTypes; // Should be able to ask this question right away.
#endif
if (typeSymbol is null)
{
return default;
}
return Create(typeSymbol, nullableAnnotation: isAnnotated ? NullableAnnotation.Annotated : nonNullTypesContext.NonNullTypes == true ? NullableAnnotation.NotAnnotated : NullableAnnotation.Unknown,
return Create(typeSymbol, nullableAnnotation: isAnnotated ? NullableAnnotation.Annotated : isNullableEnabled ? NullableAnnotation.NotAnnotated : NullableAnnotation.Unknown,
customModifiers.NullToEmpty());
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册