未验证 提交 33561d0f 编写于 作者: C Charles Stoner 提交者: GitHub

Minor changes from features/NullableReferenceTypes (#24444)

上级 d2a7c263
......@@ -7,19 +7,11 @@
namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed class BestTypeInferrer
internal static class BestTypeInferrer
{
private readonly Conversions _conversions;
private BestTypeInferrer(Conversions conversions)
{
_conversions = conversions;
}
public static TypeSymbol InferBestType(ImmutableArray<TypeSymbol> types, Conversions conversions, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
var inferrer = new BestTypeInferrer(conversions);
return inferrer.GetBestType(types, ref useSiteDiagnostics);
return GetBestType(types, conversions, ref useSiteDiagnostics);
}
/// <remarks>
......@@ -118,7 +110,7 @@ public static TypeSymbol InferBestTypeForConditionalOperator(BoundExpression exp
return InferBestType(candidateTypes.ToImmutableAndFree(), conversions, ref useSiteDiagnostics);
}
private TypeSymbol GetBestType(ImmutableArray<TypeSymbol> types, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
private static TypeSymbol GetBestType(ImmutableArray<TypeSymbol> types, Conversions conversions, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
// This code assumes that the types in the list are unique.
......@@ -148,7 +140,7 @@ private TypeSymbol GetBestType(ImmutableArray<TypeSymbol> types, ref HashSet<Dia
}
else
{
var better = Better(best, type, ref useSiteDiagnostics);
var better = Better(best, type, conversions, ref useSiteDiagnostics);
if ((object)better == null)
{
......@@ -172,7 +164,7 @@ private TypeSymbol GetBestType(ImmutableArray<TypeSymbol> types, ref HashSet<Dia
for (int i = 0; i < bestIndex; i++)
{
TypeSymbol type = types[i];
TypeSymbol better = Better(best, type, ref useSiteDiagnostics);
TypeSymbol better = Better(best, type, conversions, ref useSiteDiagnostics);
if (better != best)
{
......@@ -186,7 +178,7 @@ private TypeSymbol GetBestType(ImmutableArray<TypeSymbol> types, ref HashSet<Dia
/// <summary>
/// Returns the better type amongst the two, with some possible modifications (dynamic/object or tuple names).
/// </summary>
private TypeSymbol Better(TypeSymbol type1, TypeSymbol type2, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
private static TypeSymbol Better(TypeSymbol type1, TypeSymbol type2, Conversions conversions, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
// Anything is better than an error sym.
if (type1.IsErrorType())
......@@ -199,8 +191,8 @@ private TypeSymbol Better(TypeSymbol type1, TypeSymbol type2, ref HashSet<Diagno
return type1;
}
var t1tot2 = _conversions.ClassifyImplicitConversionFromType(type1, type2, ref useSiteDiagnostics).Exists;
var t2tot1 = _conversions.ClassifyImplicitConversionFromType(type2, type1, ref useSiteDiagnostics).Exists;
var t1tot2 = conversions.ClassifyImplicitConversionFromType(type1, type2, ref useSiteDiagnostics).Exists;
var t2tot1 = conversions.ClassifyImplicitConversionFromType(type2, type1, ref useSiteDiagnostics).Exists;
if (t1tot2 && t2tot1)
{
......@@ -216,7 +208,7 @@ private TypeSymbol Better(TypeSymbol type1, TypeSymbol type2, ref HashSet<Diagno
if (type1.Equals(type2, TypeCompareKind.IgnoreDynamicAndTupleNames))
{
return MethodTypeInferrer.MergeTupleNames(MethodTypeInferrer.MergeDynamic(type1, type2, _conversions.CorLibrary), type2);
return MethodTypeInferrer.MergeTupleNames(MethodTypeInferrer.MergeDynamic(type1, type2, conversions.CorLibrary), type2);
}
return null;
......
......@@ -703,15 +703,6 @@ public static bool IsBaseInterface(TypeSymbol baseType, TypeSymbol derivedType,
return false;
}
// IsBaseClassOfClass determines whether the purported derived type is a class, and if so,
// if the purported base type is one of its base classes.
public static bool IsBaseClassOfClass(TypeSymbol baseType, TypeSymbol derivedType, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
Debug.Assert((object)baseType != null);
Debug.Assert((object)derivedType != null);
return derivedType.IsClassType() && IsBaseClass(derivedType, baseType, ref useSiteDiagnostics);
}
// IsBaseClass returns true if and only if baseType is a base class of derivedType, period.
//
// * interfaces do not have base classes. (Structs, enums and classes other than object do.)
......@@ -2084,46 +2075,26 @@ private bool HasImplicitReferenceConversion(TypeSymbol source, TypeSymbol destin
return true;
}
if (HasImplicitConversionToInterface(source, destination, ref useSiteDiagnostics))
{
return true;
}
break;
return HasImplicitConversionToInterface(source, destination, ref useSiteDiagnostics);
case TypeKind.Interface:
// SPEC: From any interface-type S to any interface-type T, provided S is derived from T.
// NOTE: This handles variance conversions
if (HasImplicitConversionToInterface(source, destination, ref useSiteDiagnostics))
{
return true;
}
break;
return HasImplicitConversionToInterface(source, destination, ref useSiteDiagnostics);
case TypeKind.Delegate:
// SPEC: From any delegate-type to System.Delegate and the interfaces it implements.
// NOTE: This handles variance conversions.
if (HasImplicitConversionFromDelegate(source, destination, ref useSiteDiagnostics))
{
return true;
}
break;
return HasImplicitConversionFromDelegate(source, destination, ref useSiteDiagnostics);
case TypeKind.TypeParameter:
if (HasImplicitReferenceTypeParameterConversion((TypeParameterSymbol)source, destination, ref useSiteDiagnostics))
{
return true;
}
break;
return HasImplicitReferenceTypeParameterConversion((TypeParameterSymbol)source, destination, ref useSiteDiagnostics);
case TypeKind.Array:
// SPEC: From an array-type S ... to an array-type T, provided ...
// SPEC: From any array-type to System.Array and the interfaces it implements.
// SPEC: From a single-dimensional array type S[] to IList<T>, provided ...
if (HasImplicitConversionFromArray(source, destination, ref useSiteDiagnostics))
{
return true;
}
break;
return HasImplicitConversionFromArray(source, destination, ref useSiteDiagnostics);
}
// UNDONE: Implicit conversions involving type parameters that are known to be reference types.
......@@ -2140,24 +2111,26 @@ private bool HasImplicitConversionToInterface(TypeSymbol source, TypeSymbol dest
// * From any class type S to any interface type T provided S implements an interface
// convertible to T.
if (source.IsClassType())
{
return HasAnyBaseInterfaceConversion(source, destination, ref useSiteDiagnostics);
}
// * From any interface type S to any interface type T provided S implements an interface
// convertible to T.
// * From any interface type S to any interface type T provided S is not T and S is
// an interface convertible to T.
if (source.IsClassType() && HasAnyBaseInterfaceConversion(source, destination, ref useSiteDiagnostics))
{
return true;
}
if (source.IsInterfaceType() && HasAnyBaseInterfaceConversion(source, destination, ref useSiteDiagnostics))
if (source.IsInterfaceType())
{
return true;
}
if (HasAnyBaseInterfaceConversion(source, destination, ref useSiteDiagnostics))
{
return true;
}
if (source.IsInterfaceType() && source != destination && HasInterfaceVarianceConversion(source, destination, ref useSiteDiagnostics))
{
return true;
if (source != destination && HasInterfaceVarianceConversion(source, destination, ref useSiteDiagnostics))
{
return true;
}
}
return false;
......@@ -2500,19 +2473,28 @@ private bool HasVariantConversionNoCycleCheck(NamedTypeSymbol source, NamedTypeS
}
TypeParameterSymbol typeParameterSymbol = (TypeParameterSymbol)typeParameters[paramIndex];
if (typeParameterSymbol.Variance == VarianceKind.None)
{
return false;
}
if (typeParameterSymbol.Variance == VarianceKind.Out && !HasImplicitReferenceConversion(sourceTypeArgument, destinationTypeArgument, ref useSiteDiagnostics))
switch (typeParameterSymbol.Variance)
{
return false;
}
case VarianceKind.None:
return false;
if (typeParameterSymbol.Variance == VarianceKind.In && !HasImplicitReferenceConversion(destinationTypeArgument, sourceTypeArgument, ref useSiteDiagnostics))
{
return false;
case VarianceKind.Out:
if (!HasImplicitReferenceConversion(sourceTypeArgument, destinationTypeArgument, ref useSiteDiagnostics))
{
return false;
}
break;
case VarianceKind.In:
if (!HasImplicitReferenceConversion(destinationTypeArgument, sourceTypeArgument, ref useSiteDiagnostics))
{
return false;
}
break;
default:
throw ExceptionUtilities.UnexpectedValue(typeParameterSymbol.Variance);
}
}
}
......@@ -2694,7 +2676,7 @@ private bool HasExplicitReferenceConversion(TypeSymbol source, TypeSymbol destin
}
// SPEC: From any class-type S to any class-type T, provided S is a base class of T.
if (IsBaseClassOfClass(source, destination, ref useSiteDiagnostics))
if (destination.IsClassType() && IsBaseClass(destination, source, ref useSiteDiagnostics))
{
return true;
}
......
......@@ -46,21 +46,6 @@ internal sealed class LambdaSymbol : SourceMethodSymbol
_parameters = MakeParameters(compilation, unboundLambda, parameterTypes, parameterRefKinds, diagnostics);
}
public LambdaSymbol(
Symbol containingSymbol,
MessageID messageID,
SyntaxNode syntax,
bool isSynthesized)
{
_containingSymbol = containingSymbol;
_messageID = messageID;
_syntax = syntax;
_refKind = RefKind.None;
_returnType = ErrorTypeSymbol.UnknownResultType;
_isSynthesized = isSynthesized;
_parameters = ImmutableArray<ParameterSymbol>.Empty;
}
public MessageID MessageID { get { return _messageID; } }
public override MethodKind MethodKind
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册