Esempio n. 1
0
 internal static ConversionSymbol ResolveByRefConversion(Expr expr, TypeSymbol type, BindOptions options)
 {
     if (type.IsByRef && TypesMatch(expr.Datatype, type.ElementType))
     {
         return(ConversionSymbol.CreateByRef());
     }
     else
     {
         var inner = ConversionSymbol.Create(ConversionKind.Deref);
         var outer = Conversion(TypeConversion.Bound(expr, expr.Datatype.ElementType, inner), type, options);
         if (outer.Exists)
         {
             return(ConversionSymbol.Create(outer, inner));
         }
     }
     return(null);
 }
 internal static ConversionSymbol ResolveUsualConversion(Expr expr, TypeSymbol type, BindOptions options)
 {
     if (expr.Datatype.NativeType == NativeType.Usual)
     {
         if (type.NativeType == NativeType.Object)
         {
             if (options.HasFlag(BindOptions.BoxUsual))
             {
                 return(ConversionSymbol.Create(ConversionKind.Boxing));
             }
             else
             {
                 MethodSymbol converter = null;
                 ResolveConversionMethod(expr, type, Compilation.Get(NativeType.Usual).Lookup(XSharpFunctionNames.ToObject), ref converter, options);
                 if (converter != null)
                 {
                     return(ConversionSymbol.Create(ConversionKind.ImplicitUserDefined, converter));
                 }
             }
         }
         else if (type.IsByRef)
         {
             var elem  = type.ElementType;
             var inner = Conversion(expr, elem, options);
             if (inner.Exists)
             {
                 if (expr.Symbol.HasRefAccess && inner.Kind == ConversionKind.Identity)
                 {
                     return(ConversionSymbol.CreateByRef());
                 }
                 else
                 {
                     var outer = ConversionSymbol.CreateByRef();
                     return(ConversionSymbol.Create(outer, new ConversionToTemp(inner, elem)));
                 }
             }
         }
         else
         {
             MethodSymbol converter = null;
             ResolveConversionMethod(expr, Compilation.Get(NativeType.Object), Compilation.Get(NativeType.Usual).Lookup(XSharpFunctionNames.ToObject), ref converter, options);
             if (converter != null)
             {
                 var inner = ConversionSymbol.Create(ConversionKind.ImplicitUserDefined, converter);
                 var outer = type.IsReferenceType ? ConversionSymbol.Create(ConversionKind.ExplicitReference)
                     : type.IsValueType ? ConversionSymbol.Create(ConversionKind.Unboxing)
                     : ConversionSymbol.Create(ConversionKind.NoConversion);
                 if (outer.Exists)
                 {
                     return(ConversionSymbol.Create(outer, inner));
                 }
             }
         }
     }
     else if (type.NativeType == NativeType.Usual && expr.Datatype.IsReferenceType) // XXX dead code!
     {
         var inner = Conversion(expr, Compilation.Get(NativeType.Object), options | BindOptions.Explicit);
         if (inner.Exists)
         {
             var outer = Conversion(TypeConversion.Bound(expr, Compilation.Get(NativeType.Object), inner), type, options);
             if (outer.Exists)
             {
                 return(ConversionSymbol.Create(outer, inner));
             }
         }
     }
     return(null);
 }