未验证 提交 90590524 编写于 作者: R Rikki Gibson 提交者: GitHub

Merge pull request #35273 from RikkiGibson/cherry-pick-34909

Cherry-pick PR #34909
......@@ -1497,14 +1497,14 @@ internal SynthesizedAttributeData SynthesizeNullableAttribute(Symbol symbol, Typ
type.AddNullableTransforms(flagsBuilder);
Debug.Assert(flagsBuilder.Any());
Debug.Assert(flagsBuilder.Contains((byte)NullableAnnotation.NotAnnotated) || flagsBuilder.Contains((byte)NullableAnnotation.Annotated));
Debug.Assert(flagsBuilder.Contains(NullableAnnotationExtensions.NotAnnotatedAttributeValue) || flagsBuilder.Contains(NullableAnnotationExtensions.AnnotatedAttributeValue));
WellKnownMember constructor;
ImmutableArray<TypedConstant> arguments;
NamedTypeSymbol byteType = Compilation.GetSpecialType(SpecialType.System_Byte);
Debug.Assert((object)byteType != null);
if (flagsBuilder.All(flag => flag == (byte)NullableAnnotation.NotAnnotated) || flagsBuilder.All(flag => flag == (byte)NullableAnnotation.Annotated))
if (flagsBuilder.All(flag => flag == NullableAnnotationExtensions.NotAnnotatedAttributeValue) || flagsBuilder.All(flag => flag == NullableAnnotationExtensions.AnnotatedAttributeValue))
{
constructor = WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte;
arguments = ImmutableArray.Create(new TypedConstant(byteType, TypedConstantKind.Primitive, flagsBuilder[0]));
......@@ -1515,7 +1515,7 @@ internal SynthesizedAttributeData SynthesizeNullableAttribute(Symbol symbol, Typ
foreach (byte flag in flagsBuilder)
{
Debug.Assert(flag == (byte)NullableAnnotation.Oblivious || flag == (byte)NullableAnnotation.NotAnnotated || flag == (byte)NullableAnnotation.Annotated);
Debug.Assert(flag == NullableAnnotationExtensions.ObliviousAttributeValue || flag == NullableAnnotationExtensions.NotAnnotatedAttributeValue || flag == NullableAnnotationExtensions.AnnotatedAttributeValue);
constantsBuilder.Add(new TypedConstant(byteType, TypedConstantKind.Primitive, flag));
}
......
......@@ -129,7 +129,7 @@ private static ImmutableArray<FlowAnalysisAnnotations> Array(params FlowAnalysis
private static ImmutableArray<byte> Nullable(bool isNullable)
{
return ImmutableArray.Create((byte)(isNullable ? NullableAnnotation.Annotated : NullableAnnotation.NotAnnotated));
return ImmutableArray.Create(isNullable ? NullableAnnotationExtensions.AnnotatedAttributeValue : NullableAnnotationExtensions.NotAnnotatedAttributeValue);
}
internal static ImmutableArray<ImmutableArray<byte>> GetExtraAnnotations(string key)
......
......@@ -296,11 +296,11 @@ public override bool HasReferenceTypeConstraint
if (((PEModuleSymbol)this.ContainingModule).Module.HasNullableAttribute(_handle, out byte transformFlag, out _))
{
switch ((NullableAnnotation)transformFlag)
switch (transformFlag)
{
case NullableAnnotation.Annotated:
case NullableAnnotationExtensions.AnnotatedAttributeValue:
return true;
case NullableAnnotation.NotAnnotated:
case NullableAnnotationExtensions.NotAnnotatedAttributeValue:
return false;
}
}
......
......@@ -14,15 +14,15 @@ namespace Microsoft.CodeAnalysis.CSharp
internal enum NullableAnnotation : byte
{
/// <summary>
/// The type is not annotated in a context where the nullable feature is not enabled.
/// Used for interoperation with existing pre-nullable code.
/// Type is not annotated - string, int, T (including the case when T is unconstrained).
/// </summary>
Oblivious,
NotAnnotated,
/// <summary>
/// Type is not annotated - string, int, T (including the case when T is unconstrained).
/// The type is not annotated in a context where the nullable feature is not enabled.
/// Used for interoperation with existing pre-nullable code.
/// </summary>
NotAnnotated,
Oblivious,
/// <summary>
/// Type is annotated with '?' - string?, T? where T : class; and for int?, T? where T : struct.
......
......@@ -18,67 +18,54 @@ internal static class NullableAnnotationExtensions
/// <summary>
/// Join nullable annotations from the set of lower bounds for fixing a type parameter.
/// This uses the covariant merging rules.
/// This uses the covariant merging rules. (Annotated wins over Oblivious which wins over NotAnnotated)
/// </summary>
public static NullableAnnotation Join(this NullableAnnotation a, NullableAnnotation b)
{
if (a.IsAnnotated() || b.IsAnnotated())
return NullableAnnotation.Annotated;
return (a < b) ? a : b;
}
public static NullableAnnotation Join(this NullableAnnotation a, NullableAnnotation b) => (a < b) ? b : a;
/// <summary>
/// Meet two nullable annotations for computing the nullable annotation of a type parameter from upper bounds.
/// This uses the contravariant merging rules.
/// This uses the contravariant merging rules. (NotAnnotated wins over Oblivious which wins over Annotated)
/// </summary>
public static NullableAnnotation Meet(this NullableAnnotation a, NullableAnnotation b)
{
if (a.IsNotAnnotated() || b.IsNotAnnotated())
return NullableAnnotation.NotAnnotated;
return (a < b) ? a : b;
}
public static NullableAnnotation Meet(this NullableAnnotation a, NullableAnnotation b) => (a < b) ? a : b;
/// <summary>
/// Check that two nullable annotations are "compatible", which means they could be the same. Return the
/// nullable annotation to be used as a result. This uses the invariant merging rules.
/// Return the nullable annotation to use when two annotations are expected to be "compatible", which means
/// they could be the same. These are the "invariant" merging rules. (NotAnnotated wins over Annotated which wins over Oblivious)
/// </summary>
public static NullableAnnotation EnsureCompatible(this NullableAnnotation a, NullableAnnotation b)
{
if (a.IsOblivious())
return b;
if (b.IsOblivious())
return a;
return (a < b) ? a : b;
}
public static NullableAnnotation EnsureCompatible(this NullableAnnotation a, NullableAnnotation b) =>
(a, b) switch
{
(NullableAnnotation.Oblivious, _) => b,
(_, NullableAnnotation.Oblivious) => a,
_ => a < b ? a : b,
};
/// <summary>
/// Merges nullability.
/// </summary>
public static NullableAnnotation MergeNullableAnnotation(this NullableAnnotation a, NullableAnnotation b, VarianceKind variance)
{
return variance switch
public static NullableAnnotation MergeNullableAnnotation(this NullableAnnotation a, NullableAnnotation b, VarianceKind variance) =>
variance switch
{
VarianceKind.In => a.Meet(b),
VarianceKind.Out => a.Join(b),
VarianceKind.None => a.EnsureCompatible(b),
_ => throw ExceptionUtilities.UnexpectedValue(variance)
};
}
/// <summary>
/// The attribute (metadata) representation of <see cref="NullableAnnotation.NotAnnotated"/>.
/// </summary>
public const byte NotAnnotatedAttributeValue = (byte)NullableAnnotation.NotAnnotated;
public const byte NotAnnotatedAttributeValue = 1;
/// <summary>
/// The attribute (metadata) representation of <see cref="NullableAnnotation.Annotated"/>.
/// </summary>
public const byte AnnotatedAttributeValue = (byte)NullableAnnotation.Annotated;
public const byte AnnotatedAttributeValue = 2;
/// <summary>
/// The attribute (metadata) representation of <see cref="NullableAnnotation.Oblivious"/>.
/// </summary>
public const byte ObliviousAttributeValue = (byte)NullableAnnotation.Oblivious;
public const byte ObliviousAttributeValue = 0;
internal static NullabilityInfo ToNullabilityInfo(this CodeAnalysis.NullableAnnotation annotation, TypeSymbol type)
{
......
......@@ -551,15 +551,15 @@ public void AddNullableTransforms(ArrayBuilder<byte> transforms)
if (NullableAnnotation.IsOblivious() || typeSymbol.IsValueType)
{
flag = (byte)NullableAnnotation.Oblivious;
flag = NullableAnnotationExtensions.ObliviousAttributeValue;
}
else if (NullableAnnotation.IsAnnotated())
{
flag = (byte)NullableAnnotation.Annotated;
flag = NullableAnnotationExtensions.AnnotatedAttributeValue;
}
else
{
flag = (byte)NullableAnnotation.NotAnnotated;
flag = NullableAnnotationExtensions.NotAnnotatedAttributeValue;
}
transforms.Add(flag);
......@@ -597,17 +597,17 @@ public bool ApplyNullableTransforms(byte defaultTransformFlag, ImmutableArray<by
result = result.WithTypeAndModifiers(newTypeSymbol, result.CustomModifiers);
}
switch ((NullableAnnotation)transformFlag)
switch (transformFlag)
{
case NullableAnnotation.Annotated:
case NullableAnnotationExtensions.AnnotatedAttributeValue:
result = result.AsNullableReferenceType();
break;
case NullableAnnotation.NotAnnotated:
case NullableAnnotationExtensions.NotAnnotatedAttributeValue:
result = result.AsNotNullableReferenceType();
break;
case NullableAnnotation.Oblivious:
case NullableAnnotationExtensions.ObliviousAttributeValue:
if (result.NullableAnnotation != NullableAnnotation.Oblivious &&
!(result.NullableAnnotation.IsAnnotated() && oldTypeSymbol.IsNullableType())) // Preserve nullable annotation on Nullable<T>.
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册