Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 141 lines (121 sloc) 5.501 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Apache License, Version 2.0, please send an email to
* ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*
*
* ***************************************************************************/

#if FEATURE_CORE_DLR
using System.Linq.Expressions;
#else
using Microsoft.Scripting.Ast;
#endif

using System;
using System.Dynamic;
using Microsoft.Scripting.Actions;
using Microsoft.Scripting.Actions.Calls;
using Microsoft.Scripting.Utils;
using System.Threading;
using System.Diagnostics;
using IronRuby.Runtime.Conversions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Collections.Generic;

namespace IronRuby.Runtime.Calls {
    public sealed class RubyBinder : DefaultBinder {
        private readonly RubyContext/*!*/ _context;

        internal RubyBinder(RubyContext/*!*/ context){
            _context = context;
        }

        public override string GetTypeName(Type/*!*/ t) {
            return _context.GetTypeName(t, true);
        }

        public override string GetObjectTypeName(object arg) {
            return _context.GetClassDisplayName(arg);
        }

        public override bool PrivateBinding {
            get {
                return _context.DomainManager.Configuration.PrivateBinding;
            }
        }

        #region Conversions

        public override Expression ConvertExpression(Expression expr, Type toType, ConversionResultKind kind, OverloadResolverFactory context) {
            throw new InvalidOperationException("OBSOLETE");
        }

        public override bool CanConvertFrom(Type/*!*/ fromType, Type/*!*/ toType, bool toNotNullable, NarrowingLevel level) {
            return Converter.CanConvertFrom(null, fromType, toType, toNotNullable, level, false, false).IsConvertible;
        }

        public override Candidate PreferConvert(Type t1, Type t2) {
            return Converter.PreferConvert(t1, t2);
        }

        #endregion

        #region MetaObjects

        // negative start reserves as many slots at the beginning of the new array:
        internal static object/*!*/[]/*!*/ ToValues(DynamicMetaObject/*!*/[]/*!*/ args, int start) {
            var result = new object[args.Length - start];
            for (int i = Math.Max(0, -start); i < result.Length; i++) {
                result[i] = args[start + i].Value;
            }
            return result;
        }

#if DEBUG && FEATURE_FULL_CONSOLE
        // ExpressionWriter might call ToString on a live object that might dynamically invoke a method.
        // We need to prevent recursion in such case.
[ThreadStatic]
        internal static bool _DumpingExpression;

        private static int _precompiledRuleCounter;
        private static int _ruleCounter;
        private static MethodInfo _dumpViewMethod;
#endif

[Conditional("DEBUG")]
        internal static void DumpPrecompiledRule(CallSiteBinder/*!*/ binder, MemberDispatcher/*!*/ dispatcher) {
#if DEBUG && FEATURE_FULL_CONSOLE
            if (RubyOptions.ShowRules) {
                var oldColor = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("Precompiled Rule #{0}: {1}", Interlocked.Increment(ref _precompiledRuleCounter), binder);
                Console.ForegroundColor = ConsoleColor.DarkGray;
                Console.WriteLine(dispatcher);
                Console.ForegroundColor = oldColor;
            }
#endif
        }

[Conditional("DEBUG")]
        internal static void DumpRule(CallSiteBinder/*!*/ binder, BindingRestrictions/*!*/ restrictions, Expression/*!*/ expr) {
#if DEBUG && FEATURE_FULL_CONSOLE
            if (RubyOptions.ShowRules) {
                var oldColor = Console.ForegroundColor;
                try {
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("Rule #{0}: {1}", Interlocked.Increment(ref _ruleCounter), binder);
                    Console.ForegroundColor = ConsoleColor.DarkGray;
                    if (!_DumpingExpression) {
                        var d = (restrictions != BindingRestrictions.Empty) ? Expression.IfThen(restrictions.ToExpression(), expr) : expr;
                        _DumpingExpression = true;
                        try {
                            if (_dumpViewMethod == null) {
                                _dumpViewMethod = typeof(Expression).GetMethod("get_DebugView", BindingFlags.NonPublic | BindingFlags.Instance);
                            }
                            Console.WriteLine(_dumpViewMethod.Invoke(d, ArrayUtils.EmptyObjects));
                            Console.WriteLine();
                        } catch {
                            // nop
                        }
                    }
                } finally {
                    _DumpingExpression = false;
                    Console.ForegroundColor = oldColor;
                }
            }
#endif
        }

        #endregion
    }
}
Something went wrong with that request. Please try again.