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

Minor changes from features/NullableReferenceTypes (#24444)

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