Esempio n. 1
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            switchControl = ViewHelpers.GetView <UISwitch> (nativeView);

            if (switchControl == null)
            {
                throw new InvalidOperationException("Cannot convert " + nativeView + " to UISwitch");
            }

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                isChecked = switchControl.On;
                enabled   = switchControl.Enabled;
            }
            else
            {
                switchControl.On      = isChecked;
                switchControl.Enabled = enabled;
            }

            switchControl.ValueChanged += SwitchControl_ValueChanged;
        }
Esempio n. 2
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            editText = ViewHelpers.GetView <Android.Widget.EditText> (nativeView);

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                text        = editText.Text;
                placeholder = editText.Hint;
                enabled     = editText.Enabled;
            }
            else
            {
                editText.Text    = text;
                editText.Hint    = placeholder;
                editText.Enabled = enabled;
            }

            editText.TextChanged += EditText_TextChanged;
        }
Esempio n. 3
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            textField = ViewHelpers.GetView <NSTextField> (nativeView);

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                text        = textField.StringValue;
                placeholder = textField.PlaceholderString;
                enabled     = textField.Enabled;
            }
            else
            {
                textField.StringValue       = text;
                textField.PlaceholderString = placeholder;
                textField.Enabled           = enabled;
            }

            textField.Changed += TextField_Changed;
        }
Esempio n. 4
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            textField = ViewHelpers.GetView <UIKit.UITextField> (nativeView);

            if (textField == null)
            {
                throw new InvalidOperationException("Cannot convert " + nativeView + " to UITextField");
            }

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                text        = textField.Text;
                placeholder = textField.Placeholder;
                enabled     = textField.Enabled;
            }
            else
            {
                textField.Text        = text;
                textField.Placeholder = placeholder;
                textField.Enabled     = enabled;
            }

            textField.ValueChanged += TextField_ValueChanged;
        }
Esempio n. 5
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            switchControl = ViewHelpers.GetView <NSButton> (nativeView);
            switchControl.SetButtonType(NSButtonType.Switch);
            switchControl.AllowsMixedState = false;

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                isChecked = switchControl.State == NSCellStateValue.On;
                enabled   = switchControl.Enabled;
            }
            else
            {
                switchControl.State   = isChecked ? NSCellStateValue.On : NSCellStateValue.Off;
                switchControl.Enabled = enabled;
            }

            switchControl.Activated += SwitchControl_Activated;
        }
Esempio n. 6
0
 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
         {
             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)
     {
         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);
 }
Esempio n. 7
0
        internal static UnaryOperatorSymbol BindUnaryOperation(UnaryExpr expr, UnaryOperatorKind kind, BindOptions options)
        {
            if (options.HasFlag(BindOptions.Logic))
            {
                Convert(ref expr.Expr, Compilation.Get(NativeType.Boolean), options);
            }

            var res = UnaryOperation(kind, ref expr.Expr, options);

            if (res != null)
            {
                return(res);
            }

            throw UnaryOperationError(expr, kind, options);
        }
Esempio n. 8
0
        internal static bool CheckBinaryOperator(Expr left, Expr right, MethodSymbol m,
                                                 ref ConversionSymbol lconv, ref ConversionSymbol rconv, BindOptions options)
        {
            var method = m.Method;

            if (!m.Method.IsStatic || (options.HasFlag(BindOptions.Special) && !m.Method.IsSpecialName))
            {
                return(false);
            }
            var parameters = method.GetParameters();

            if (parameters.Length != 2)
            {
                return(false);
            }
            var ltype = FindType(parameters[0].ParameterType);
            var rtype = FindType(parameters[1].ParameterType);

            if (TypesMatch(ltype, left.Datatype) && TypesMatch(rtype, right.Datatype))
            {
                lconv = ConversionSymbol.Create(ConversionKind.Identity);
                rconv = ConversionSymbol.Create(ConversionKind.Identity);
                return(true);
            }
            var _lconv = Conversion(left, ltype, options);
            var _rconv = Conversion(right, rtype, options);

            if (_lconv.IsImplicit && _rconv.IsImplicit)
            {
                if (lconv == null && rconv == null)
                {
                    lconv = _lconv;
                    rconv = _rconv;
                    return(true);
                }
                var cost  = lconv?.Cost + rconv?.Cost;
                var _cost = _lconv.Cost + _rconv.Cost;
                if (_cost < cost)
                {
                    lconv = _lconv;
                    rconv = _rconv;
                    return(true);
                }
            }
            return(false);
        }
Esempio n. 9
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            textField = ViewHelpers.GetView <NSTextField> (nativeView);

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                text = textField.StringValue;
            }
            else
            {
                textField.StringValue = text;
            }
        }
Esempio n. 10
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            label = ViewHelpers.GetView <UILabel> (nativeView);

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                text = label.Text;
            }
            else
            {
                label.Text = text;
            }
        }
Esempio n. 11
0
        internal static UnaryOperatorSymbol UnaryOperation(UnaryOperatorKind kind, ref Expr expr, BindOptions options)
        {
            var sym = UnaryOperatorEasyOut.ClassifyOperation(kind, expr.Datatype);

            if (sym != null)
            {
                Convert(ref expr, sym.Type, options);
                return(sym);
            }

            // User-defined operators
            {
                var op = UserDefinedUnaryOperator(kind, ref expr, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Dynamic with usual
            if (options.HasFlag(BindOptions.AllowDynamic))
            {
                var op = DynamicUnaryOperator(kind, ref expr, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Enum operations
            {
                var op = EnumUnaryOperator(kind, ref expr, options);
                if (op != null)
                {
                    return(op);
                }
            }

            return(null);
        }
Esempio n. 12
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            button = ViewHelpers.GetView <UIButton> (nativeView);

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                enabled = button.Enabled;
                text    = button.Title(UIControlState.Normal);
            }
            else
            {
                button.Enabled = enabled;
                button.SetTitle(text, UIControlState.Normal);
            }

            button.TouchUpInside += Button_TouchUpInside;
        }
Esempio n. 13
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            button = ViewHelpers.GetView <NSButton> (nativeView);

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                enabled = button.Enabled;
                text    = button.Title;
            }
            else
            {
                button.Enabled = enabled;
                button.Title   = text;
            }

            button.Activated += Button_Activated;
        }
        static bool CheckConversionMethod(Expr expr, TypeSymbol type, MethodSymbol m, BindOptions options)
        {
            var method = m.Method;

            if (!m.Method.IsStatic || (options.HasFlag(BindOptions.Special) && !m.Method.IsSpecialName))
            {
                return(false);
            }
            if (!TypesMatch(FindType(m.Method.ReturnType), type))
            {
                return(false);
            }
            var parameters = method.GetParameters();

            if (parameters.Length != 1)
            {
                return(false);
            }
            if (!TypesMatch(FindType(parameters[0].ParameterType), expr.Datatype))
            {
                return(false);
            }
            return(true);
        }
 internal static ConversionSymbol ResolveEnumConversion(Expr expr, TypeSymbol type, BindOptions options)
 {
     if (expr.Datatype.IsEnum)
     {
         if (TypesMatch(expr.Datatype.EnumUnderlyingType, type))
         {
             return(ConversionSymbol.Create(ConversionKind.ImplicitEnumeration));
         }
         else
         {
             var inner = ConversionSymbol.Create(ConversionKind.ImplicitEnumeration);
             var outer = Conversion(TypeConversion.Bound(expr, expr.Datatype.EnumUnderlyingType, inner), type, options);
             if (outer.Exists)
             {
                 return(ConversionSymbol.Create(outer, inner));
             }
         }
     }
     if (type.IsEnum && options.HasFlag(BindOptions.Explicit))
     {
         if (TypesMatch(type.EnumUnderlyingType, expr.Datatype))
         {
             return(ConversionSymbol.Create(ConversionKind.ExplicitEnumeration));
         }
         else
         {
             var inner = Conversion(expr, type.EnumUnderlyingType, options);
             if (inner.Exists)
             {
                 var outer = ConversionSymbol.Create(ConversionKind.ExplicitEnumeration);
                 return(ConversionSymbol.Create(outer, inner));
             }
         }
     }
     return(null);
 }
Esempio n. 16
0
        /// <inheritdoc/>
        public void BindToNative(object nativeView, BindOptions options = BindOptions.None)
        {
            if (nativeView == null)
            {
                throw new ArgumentNullException("nativeView");
            }

            UnbindFromNative();

            switchControl = ViewHelpers.GetView <Android.Widget.Switch> (nativeView);

            if (options.HasFlag(BindOptions.PreserveNativeProperties))
            {
                isChecked = switchControl.Checked;
                enabled   = switchControl.Enabled;
            }
            else
            {
                switchControl.Checked = isChecked;
                switchControl.Enabled = enabled;
            }

            switchControl.CheckedChange += SwitchControl_CheckedChange;
        }
Esempio n. 17
0
        internal static BinaryOperatorSymbol UserDefinedBinaryOperator(BinaryOperatorKind kind, ref Expr left, ref Expr right, BindOptions options)
        {
            MethodSymbol     mop   = null;
            ConversionSymbol lconv = null;
            ConversionSymbol rconv = null;

            bool hasUsual = left.Datatype.NativeType == NativeType.Usual || right.Datatype.NativeType == NativeType.Usual;

            if (options.HasFlag(BindOptions.AllowInexactComparisons))
            {
                bool hasString   = left.Datatype.NativeType == NativeType.String || right.Datatype.NativeType == NativeType.String;
                bool bothStrings = left.Datatype.NativeType == NativeType.String && right.Datatype.NativeType == NativeType.String;

                switch (kind)
                {
                case BinaryOperatorKind.Equal:
                    if (bothStrings)
                    {
                        ResolveBinaryOperator(left, right, Compilation.Get(WellKnownMembers.XSharp_RT_Functions___StringEquals), ref mop, ref lconv, ref rconv, options);
                    }
                    else if (hasString)
                    {
                        ResolveBinaryOperator(left, right, Compilation.Get(NativeType.Usual).Lookup(OperatorNames.__UsualInExactEquals), ref mop, ref lconv, ref rconv, options);
                    }
                    break;

                case BinaryOperatorKind.NotEqual:
                    if (bothStrings)
                    {
                        ResolveBinaryOperator(left, right, Compilation.Get(WellKnownMembers.XSharp_RT_Functions___StringNotEquals), ref mop, ref lconv, ref rconv, options);
                    }
                    else if (hasString)
                    {
                        ResolveBinaryOperator(left, right, Compilation.Get(NativeType.Usual).Lookup(OperatorNames.__UsualInExactNotEquals), ref mop, ref lconv, ref rconv, options);
                    }
                    break;

                case BinaryOperatorKind.GreaterThan:
                case BinaryOperatorKind.LessThan:
                case BinaryOperatorKind.GreaterThanOrEqual:
                case BinaryOperatorKind.LessThanOrEqual:
                    if (bothStrings)
                    {
                        ResolveBinaryOperator(left, right, Compilation.Get(WellKnownMembers.XSharp_RT_Functions___StringCompare), ref mop, ref lconv, ref rconv, options);
                    }
                    break;
                }
            }
            else
            {
                switch (kind)
                {
                case BinaryOperatorKind.Equal:
                case BinaryOperatorKind.NotEqual:
                case BinaryOperatorKind.GreaterThan:
                case BinaryOperatorKind.LessThan:
                case BinaryOperatorKind.GreaterThanOrEqual:
                case BinaryOperatorKind.LessThanOrEqual:
                    if (left.Datatype.NativeType == NativeType.String && right.Datatype.NativeType == NativeType.String)
                    {
                        ResolveBinaryOperator(left, right, Compilation.Get(WellKnownMembers.System_String_CompareOrdinal), ref mop, ref lconv, ref rconv, options);
                    }
                    break;
                }
            }

            if (mop == null)
            {
                var name = BinaryOperatorSymbol.OperatorName(kind);
                if (name != null)
                {
                    ResolveBinaryOperator(left, right, left.Datatype.Lookup(name), ref mop, ref lconv, ref rconv, options | BindOptions.Special);
                    ResolveBinaryOperator(left, right, right.Datatype.Lookup(name), ref mop, ref lconv, ref rconv, options | BindOptions.Special);
                }
            }

            if (mop == null && kind == BinaryOperatorKind.Exponent)
            {
                ResolveBinaryOperator(left, right, Compilation.Get(WellKnownMembers.XSharp_RT_Functions_POW), ref mop, ref lconv, ref rconv, options);
                if (hasUsual)
                {
                    ResolveBinaryOperator(left, right, left.Datatype.Lookup(OperatorNames.__UsualExponent), ref mop, ref lconv, ref rconv, options);
                    ResolveBinaryOperator(left, right, right.Datatype.Lookup(OperatorNames.__UsualExponent), ref mop, ref lconv, ref rconv, options);
                }
            }

            if (mop != null)
            {
                var op = BinaryOperatorSymbol.Create(kind, mop, lconv, rconv);
                ApplyBinaryOperator(ref left, ref right, op);
                return(op);
            }

            return(null);
        }
        internal static ConversionSymbol Conversion(Expr expr, TypeSymbol type, BindOptions options)
        {
            var noConversion = ConversionKind.NoConversion;

            var conversion = ConversionEasyOut.ClassifyConversion(expr.Datatype, type);

            if (expr.Symbol.IsConstant() || expr.IsConstant)
            {
                options |= BindOptions.Explicit;
            }

            if (conversion != ConversionKind.NoConversion)
            {
                var conv = ConversionSymbol.Create(conversion);
                if (!conv.IsCast && options.HasFlag(BindOptions.Explicit) || conv.IsImplicit)
                {
                    return(conv);
                }
                if (conv.IsCast && options.HasFlag(BindOptions.Cast))
                {
                    return(conv);
                }
                if (conv.IsExplicit && conv.Kind == ConversionKind.ExplicitNumeric && options.HasFlag(BindOptions.AllowImplicitNarrowingConversions))
                {
                    return(conv); // TODO nvk: this should raise a warning!
                }
                if (conv.Exists)
                {
                    noConversion = ConversionKind.NoImplicitConversion;
                }
            }

            if (TypesMatch(expr.Datatype, type))
            {
                return(ConversionSymbol.Create(ConversionKind.Identity));
            }

            if (type.Type.IsGenericType || expr.Datatype.Type.IsGenericType)
            {
                return(ConversionSymbol.Create(noConversion));
            }

            MethodSymbol converter = null;

            ResolveUserDefinedConversion(expr, type, expr.Datatype.Lookup(OperatorNames.Implicit), type.Lookup(OperatorNames.Implicit), ref converter, options | BindOptions.Special);
            if (converter != null)
            {
                return(ConversionSymbol.Create(ConversionKind.ImplicitUserDefined, converter));
            }

            if (options.HasFlag(BindOptions.Explicit))
            {
                ResolveUserDefinedConversion(expr, type, expr.Datatype.Lookup(OperatorNames.Explicit), type.Lookup(OperatorNames.Explicit), ref converter, options | BindOptions.Special);
                if (converter != null)
                {
                    return(ConversionSymbol.Create(ConversionKind.ExplicitUserDefined, converter));
                }
            }

            {
                var conv = ResolveUsualConversion(expr, type, options);
                if (conv != null)
                {
                    return(conv);
                }
            }

            if (type.IsByRef != expr.Datatype.IsByRef)
            {
                var conv = ResolveByRefConversion(expr, type, options);
                if (conv != null)
                {
                    return(conv);
                }
            }

            if (type.NativeType == NativeType.Object)
            {
                if (expr.Datatype.Type.IsValueType)
                {
                    return(ConversionSymbol.Create(ConversionKind.Boxing));
                }
                else
                {
                    return(ConversionSymbol.Create(ConversionKind.ImplicitReference));
                }
            }
            else if (expr.Datatype.NativeType == NativeType.Object)
            {
                if (!options.HasFlag(BindOptions.AllowDynamic))
                {
                    if (options.HasFlag(BindOptions.Explicit))
                    {
                        return(type.IsValueType ? ConversionSymbol.Create(ConversionKind.Unboxing) : ConversionSymbol.Create(ConversionKind.ExplicitReference));
                    }
                    else
                    {
                        noConversion = ConversionKind.NoImplicitConversion;
                    }
                }
            }
            else if (type.IsReferenceType && expr.Datatype.IsReferenceType)
            {
                if (expr.Datatype.IsSubclassOf(type))
                {
                    return(ConversionSymbol.Create(ConversionKind.ImplicitReference));
                }
                if (type.IsSubclassOf(expr.Datatype))
                {
                    if (options.HasFlag(BindOptions.Explicit))
                    {
                        return(ConversionSymbol.Create(ConversionKind.ExplicitReference));
                    }
                    else
                    {
                        noConversion = ConversionKind.NoImplicitConversion;
                    }
                }
            }

            {
                var conv = ResolveEnumConversion(expr, type, options);
                if (conv != null)
                {
                    return(conv);
                }
            }

            if (options.HasFlag(BindOptions.AllowDynamic))
            {
                var conv = ResolveDynamicConversion(expr, type, options);
                if (conv != null)
                {
                    return(conv);
                }
            }

            if (!options.HasFlag(BindOptions.Explicit) && noConversion == ConversionKind.NoConversion)
            {
                ResolveUserDefinedConversion(expr, type, expr.Datatype.Lookup(OperatorNames.Explicit), type.Lookup(OperatorNames.Explicit), ref converter, options | BindOptions.Special);
                if (converter != null)
                {
                    noConversion = ConversionKind.NoImplicitConversion;
                }
            }

            return(ConversionSymbol.Create(noConversion));
        }
Esempio n. 19
0
 public IEnumerable <IBinder> Find(BindOptions option)
 {
     return(this.Where(b => option.HasFlag(b.BindOption)));
 }
Esempio n. 20
0
        internal static BinaryOperatorSymbol BinaryOperation(BinaryOperatorKind kind, ref Expr left, ref Expr right, BindOptions options)
        {
            var sym = BinaryOperatorEasyOut.ClassifyOperation(kind, left.Datatype, right.Datatype);

            if (options.HasFlag(BindOptions.AllowInexactComparisons) && sym != null)
            {
                switch (sym.Kind)
                {
                case BinaryOperatorKind.EqString:
                case BinaryOperatorKind.EqStringObject:
                case BinaryOperatorKind.EqObjectString:
                case BinaryOperatorKind.NeqString:
                case BinaryOperatorKind.NeqStringObject:
                case BinaryOperatorKind.NeqObjectString:
                    sym = null;
                    break;
                }
            }

            if (sym != null)
            {
                Convert(ref left, sym.TypeOfOp, options);
                Convert(ref right, sym.TypeOfOp, options);
                return(sym);
            }

            // User-defined operators
            {
                var op = UserDefinedBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Symbol/string operations
            {
                var op = SymbolAndStringBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Dynamic with usual
            if (options.HasFlag(BindOptions.AllowDynamic))
            {
                var op = DynamicBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Emun operations
            {
                var op = EnumBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            return(null);
        }
Esempio n. 21
0
        internal MemberSymbol TryBindCall(Expr expr, Symbol symbol, ArgList args, out Expr self, out Expr writeBack, ref OverloadResult ovRes, BindOptions options)
        {
            self      = (expr as MemberAccessExpr)?.Expr;
            writeBack = null;

            bool isStatic = self == null;
            var  matching = new List <OverloadResult>();

            if ((symbol as MethodSymbol)?.Method.IsStatic == isStatic || symbol is ConstructorSymbol)
            {
                CheckArguments(symbol as MemberSymbol, ((MethodBaseSymbol)symbol).Parameters, args, ref ovRes, options);
            }
            else if ((symbol as SymbolList)?.HasMethodBase == true)
            {
                var methods = symbol as SymbolList;

                for (int i = 0; i < methods.Symbols.Count; i++)
                {
                    var m = methods.Symbols[i];
                    if ((m as MethodSymbol)?.Method.IsStatic == isStatic || m is ConstructorSymbol)
                    {
                        CheckArguments(m as MemberSymbol, ((MethodBaseSymbol)m).Parameters, args, ref ovRes, options);
                        if (ovRes?.Exact == true)
                        {
                            break;
                        }
                        if (ovRes != null)
                        {
                            if (!matching.Contains(ovRes))
                            {
                                matching.Add(ovRes);
                            }
                            if (ovRes.Equivalent != null && !matching.Contains(ovRes.Equivalent))
                            {
                                matching.Add(ovRes.Equivalent);
                            }
                        }
                    }
                }
            }

            if (ovRes?.Unique == true)
            {
                ApplyConversions(args, ovRes, out writeBack);
                return(ovRes.Symbol);
            }
            // Add automatic overload resolution
            if (ovRes != null && !ovRes.Unique && ovRes.Equivalent != null)
            {
                var ov1   = ovRes.Symbol;
                var ov2   = ovRes.Equivalent.Symbol;
                var func1 = ov1.DeclaringType.FullName;
                var func2 = ov2.DeclaringType.FullName;

                if (func1 != func2 && func1.StartsWith("XSharp") && func2.StartsWith("XSharp"))
                {
                    switch (func1)
                    {
                    case XSharpSpecialNames.XSharpVOFunctionsClass:
                    case XSharpSpecialNames.XSharpDataFunctionsClass:
                    case XSharpSpecialNames.XSharpVFPFunctionsClass:
                    case XSharpSpecialNames.XSharpXPPFunctionsClass:
                        // functions in specific runtime files override generic files
                        return(ovRes.Symbol);

                    case XSharpSpecialNames.XSharpRTFunctionsClass:
                        if (func2 == XSharpSpecialNames.XSharpCoreFunctionsClass)
                        {
                            // functions in specific runtime files override generic files
                            return(ovRes.Symbol);
                        }
                        break;
                    }
                    switch (func2)
                    {
                    case XSharpSpecialNames.XSharpVOFunctionsClass:
                    case XSharpSpecialNames.XSharpDataFunctionsClass:
                    case XSharpSpecialNames.XSharpVFPFunctionsClass:
                    case XSharpSpecialNames.XSharpXPPFunctionsClass:
                        // functions in specific runtime files override generic files
                        return(ovRes.Equivalent.Symbol);

                    case XSharpSpecialNames.XSharpRTFunctionsClass:
                        if (func1 == XSharpSpecialNames.XSharpCoreFunctionsClass)
                        {
                            // functions in specific runtime files override generic files
                            return(ovRes.Equivalent.Symbol);
                        }
                        break;
                    }
                }
            }
            if (matching.Count > 1 && ovRes.Valid && Options.Resolver != null)
            {
                var res = AskUserForCorrectOverload(matching, args);
                if (res != null)
                {
                    ovRes = res;
                    ApplyConversions(args, ovRes, out writeBack);
                    return(ovRes.Symbol);
                }
            }
            if (options.HasFlag(BindOptions.AllowDynamic) && expr != null && ovRes?.Valid != true)
            {
                if (symbol is DynamicExprSymbol symbolExpr)
                {
                    expr = self;
                    self = null;
                    Convert(ref expr, Compilation.Get(NativeType.Usual), options);
                    ApplyUsualConversions(args, out writeBack);
                    var obj       = new Arg(expr ?? LiteralExpr.Bound(Constant.Create(null)));
                    var name      = new Arg(symbolExpr.Name);
                    var arguments = ApplyUsualConversions(args, out writeBack);
                    args.Args.Clear();
                    args.Args.Add(obj);
                    args.Args.Add(name);
                    args.Args.Add(arguments);
                    // todo: Check for ref arguments and handle writeback from arguments array
                    return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend));
                }
                else if (symbol is DynamicSymbol symbolDynamic)
                {
                    expr = self;
                    self = null;
                    Convert(ref expr, Compilation.Get(NativeType.Usual), options);
                    var obj       = new Arg(expr ?? LiteralExpr.Bound(Constant.Create(null)));
                    var name      = new Arg(LiteralExpr.Bound(Constant.Create(symbolDynamic.Name)));
                    var arguments = ApplyUsualConversions(args, out writeBack);
                    args.Args.Clear();
                    args.Args.Add(obj);
                    args.Args.Add(name);
                    args.Args.Add(arguments);
                    // todo: Check for ref arguments and handle writeback from arguments array
                    return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend));
                }
                else if (symbol.Type()?.IsUsualOrObject() == true)
                {
                    self = null;
                    Convert(ref expr, Compilation.Get(NativeType.Usual), options);
                    ApplyUsualConversions(args, out writeBack);
                    var obj       = new Arg(expr);
                    var name      = new Arg(LiteralExpr.Bound(Constant.Create(SystemNames.DelegateInvokeName)));
                    var arguments = ApplyUsualConversions(args, out writeBack);
                    args.Args.Clear();
                    args.Args.Add(obj);
                    args.Args.Add(name);
                    args.Args.Add(arguments);
                    // todo: Check for ref arguments and handle writeback from arguments array
                    return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend));
                }
            }

            return(null);
        }
Esempio n. 22
0
        internal static MemberSymbol TryBindCall(Expr expr, Symbol symbol, ArgList args, out Expr self, ref OverloadResult ovRes, BindOptions options)
        {
            self = (expr as MemberAccessExpr)?.Expr;

            bool isStatic = self == null;

            if ((symbol as MethodSymbol)?.Method.IsStatic == isStatic || symbol is ConstructorSymbol)
            {
                CheckArguments(symbol as MemberSymbol, ((MethodBaseSymbol)symbol).Parameters, args, ref ovRes, options);
            }
            else if ((symbol as SymbolList)?.HasMethodBase == true)
            {
                var methods = symbol as SymbolList;
                for (int i = 0; i < methods.Symbols.Count; i++)
                {
                    var m = methods.Symbols[i];
                    if ((m as MethodSymbol)?.Method.IsStatic == isStatic || m is ConstructorSymbol)
                    {
                        CheckArguments(m as MemberSymbol, ((MethodBaseSymbol)m).Parameters, args, ref ovRes, options);
                        if (ovRes?.Exact == true)
                        {
                            break;
                        }
                    }
                }
            }

            if (ovRes?.Unique == true)
            {
                ApplyConversions(args, ovRes);
                return(ovRes.Symbol);
            }

            if (options.HasFlag(BindOptions.AllowDynamic) && expr != null && ovRes?.Valid != true)
            {
                if (symbol is DynamicExprSymbol symbolExpr)
                {
                    expr = self;
                    self = null;
                    Convert(ref expr, Compilation.Get(NativeType.Usual), options);
                    var obj       = new Arg(expr ?? LiteralExpr.Bound(Constant.Create(null)));
                    var name      = new Arg(symbolExpr.Name);
                    var arguments = new Arg(LiteralArray.Bound(args.Args));
                    args.Args.Clear();
                    args.Args.Add(obj);
                    args.Args.Add(name);
                    args.Args.Add(arguments);
                    return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend));
                }
                else if (symbol is DynamicSymbol symbolDynamic)
                {
                    expr = self;
                    self = null;
                    Convert(ref expr, Compilation.Get(NativeType.Usual), options);
                    var obj       = new Arg(expr ?? LiteralExpr.Bound(Constant.Create(null)));
                    var name      = new Arg(LiteralExpr.Bound(Constant.Create(symbolDynamic.Name)));
                    var arguments = new Arg(LiteralArray.Bound(args.Args));
                    args.Args.Clear();
                    args.Args.Add(obj);
                    args.Args.Add(name);
                    args.Args.Add(arguments);
                    return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend));
                }
                else if (symbol.Type()?.IsUsualOrObject() == true)
                {
                    self = null;
                    Convert(ref expr, Compilation.Get(NativeType.Usual), options);
                    var obj       = new Arg(expr);
                    var name      = new Arg(LiteralExpr.Bound(Constant.Create(SystemNames.DelegateInvokeName)));
                    var arguments = new Arg(LiteralArray.Bound(args.Args));
                    args.Args.Clear();
                    args.Args.Add(obj);
                    args.Args.Add(name);
                    args.Args.Add(arguments);
                    return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend));
                }
            }

            return(null);
        }
Esempio n. 23
0
        internal static BinaryOperatorSymbol BinaryOperation(BinaryOperatorKind kind, ref Expr left, ref Expr right, BindOptions options)
        {
            // When one or both of the datatypes is Usual or Object then convert to Usual and let
            // the operators in the Usual type handle the binary operation
            if (left.Datatype.IsUsualOrObject() || right.Datatype.IsUsualOrObject())
            {
                Convert(ref left, Compilation.Get(NativeType.Usual), options);
                Convert(ref right, Compilation.Get(NativeType.Usual), options);
            }
            var sym = BinaryOperatorEasyOut.ClassifyOperation(kind, left.Datatype, right.Datatype);

            if (options.HasFlag(BindOptions.AllowInexactComparisons) && sym != null)
            {
                switch (sym.Kind)
                {
                case BinaryOperatorKind.EqString:
                case BinaryOperatorKind.EqStringObject:
                case BinaryOperatorKind.EqObjectString:
                case BinaryOperatorKind.NeqString:
                case BinaryOperatorKind.NeqStringObject:
                case BinaryOperatorKind.NeqObjectString:
                    sym = null;
                    break;
                }
            }

            if (sym != null)
            {
                Convert(ref left, sym.TypeOfOp, options);
                Convert(ref right, sym.TypeOfOp, options);
                return(sym);
            }

            // User-defined operators
            {
                var op = UserDefinedBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Symbol/string operations
            {
                var op = SymbolAndStringBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Dynamic with usual
            if (options.HasFlag(BindOptions.AllowDynamic))
            {
                var op = DynamicBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Emun operations
            {
                var op = EnumBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            return(null);
        }