CConversions
using Microsoft.CSharp.RuntimeBinder.Syntax;
namespace Microsoft.CSharp.RuntimeBinder.Semantics
{
internal static class CConversions
{
public static bool FImpRefConv(CType typeSrc, CType typeDst)
{
if (typeSrc.IsReferenceType)
return SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst);
return false;
}
public static bool FExpRefConv(CType typeSrc, CType typeDst)
{
if (typeSrc.IsReferenceType && typeDst.IsReferenceType) {
if (SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst) || SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc))
return true;
if ((typeSrc.IsInterfaceType && typeDst is TypeParameterType) || (typeSrc is TypeParameterType && typeDst.IsInterfaceType))
return true;
AggregateType aggregateType = typeSrc as AggregateType;
if (aggregateType != null) {
AggregateType aggregateType2 = typeDst as AggregateType;
if (aggregateType2 != null) {
AggregateSymbol owningAggregate = aggregateType.OwningAggregate;
AggregateSymbol owningAggregate2 = aggregateType2.OwningAggregate;
if ((owningAggregate.IsClass() && !owningAggregate.IsSealed() && owningAggregate2.IsInterface()) || (owningAggregate.IsInterface() && owningAggregate2.IsClass() && !owningAggregate2.IsSealed()) || (owningAggregate.IsInterface() && owningAggregate2.IsInterface()))
return true;
}
}
ArrayType arrayType = typeSrc as ArrayType;
if (arrayType != null) {
ArrayType arrayType2 = typeDst as ArrayType;
if (arrayType2 != null) {
if (arrayType.Rank == arrayType2.Rank && arrayType.IsSZArray == arrayType2.IsSZArray)
return FExpRefConv(arrayType.ElementType, arrayType2.ElementType);
return false;
}
if (!arrayType.IsSZArray || !typeDst.IsInterfaceType)
return false;
AggregateType aggregateType3 = (AggregateType)typeDst;
TypeArray typeArgsAll = aggregateType3.TypeArgsAll;
if (typeArgsAll.Count != 1)
return false;
AggregateSymbol predefAgg = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_ILIST);
AggregateSymbol predefAgg2 = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST);
if ((predefAgg == null || !SymbolLoader.IsBaseAggregate(predefAgg, aggregateType3.OwningAggregate)) && (predefAgg2 == null || !SymbolLoader.IsBaseAggregate(predefAgg2, aggregateType3.OwningAggregate)))
return false;
return FExpRefConv(arrayType.ElementType, typeArgsAll[0]);
}
ArrayType arrayType3 = typeDst as ArrayType;
if (arrayType3 != null) {
AggregateType aggregateType4 = typeSrc as AggregateType;
if (aggregateType4 != null) {
if (SymbolLoader.HasIdentityOrImplicitReferenceConversion(SymbolLoader.GetPredefindType(PredefinedType.PT_ARRAY), typeSrc))
return true;
if (!arrayType3.IsSZArray || !typeSrc.IsInterfaceType || aggregateType4.TypeArgsAll.Count != 1)
return false;
AggregateSymbol predefAgg3 = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_ILIST);
AggregateSymbol predefAgg4 = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST);
if ((predefAgg3 == null || !SymbolLoader.IsBaseAggregate(predefAgg3, aggregateType4.OwningAggregate)) && (predefAgg4 == null || !SymbolLoader.IsBaseAggregate(predefAgg4, aggregateType4.OwningAggregate)))
return false;
CType elementType = arrayType3.ElementType;
CType cType = aggregateType4.TypeArgsAll[0];
if (elementType != cType)
return FExpRefConv(elementType, cType);
return true;
}
}
if (HasGenericDelegateExplicitReferenceConversion(typeSrc, typeDst))
return true;
} else {
if (typeSrc.IsReferenceType)
return SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst);
if (typeDst.IsReferenceType)
return SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc);
}
return false;
}
public static bool HasGenericDelegateExplicitReferenceConversion(CType source, CType target)
{
AggregateType aggregateType = target as AggregateType;
if (aggregateType != null)
return HasGenericDelegateExplicitReferenceConversion(source, aggregateType);
return false;
}
public static bool HasGenericDelegateExplicitReferenceConversion(CType pSource, AggregateType pTarget)
{
AggregateType aggregateType = pSource as AggregateType;
if (aggregateType == null || !aggregateType.IsDelegateType || !pTarget.IsDelegateType || aggregateType.OwningAggregate != pTarget.OwningAggregate || SymbolLoader.HasIdentityOrImplicitReferenceConversion(aggregateType, pTarget))
return false;
TypeArray typeVarsAll = aggregateType.OwningAggregate.GetTypeVarsAll();
TypeArray typeArgsAll = aggregateType.TypeArgsAll;
TypeArray typeArgsAll2 = pTarget.TypeArgsAll;
for (int i = 0; i < typeVarsAll.Count; i++) {
CType cType = typeArgsAll[i];
CType cType2 = typeArgsAll2[i];
if (cType != cType2) {
TypeParameterType typeParameterType = (TypeParameterType)typeVarsAll[i];
if (typeParameterType.Invariant)
return false;
if (typeParameterType.Covariant) {
if (!FExpRefConv(cType, cType2))
return false;
} else if (typeParameterType.Contravariant && (!cType.IsReferenceType || !cType2.IsReferenceType)) {
return false;
}
}
}
return true;
}
public static bool FWrappingConv(CType typeSrc, CType typeDst)
{
NullableType nullableType = typeDst as NullableType;
if (nullableType != null)
return typeSrc == nullableType.UnderlyingType;
return false;
}
public static bool FUnwrappingConv(CType typeSrc, CType typeDst)
{
return FWrappingConv(typeDst, typeSrc);
}
}
}