Пример #1
0
        internal static bool TryResolveOverload(
            DynamicMetaObjectBinder binder,
            Types.TotemType type,
            CallInfo callInfo,
            string name,
            IEnumerable<Tuple<MethodInfo, Types.TotemType.DynamicFlags>> methodSetups,
            DynamicMetaObject target,
            IList<DynamicMetaObject> args,
            out DynamicMetaObject result,
            int nonCountingArgs = 0,
            NarrowingLevel minLevel = NarrowingLevel.None,
            NarrowingLevel maxLevel = NarrowingLevel.All)
        {
            CodeContext context;
            Expression contextExpression;
            if (args.Count == callInfo.ArgumentCount + 1 + nonCountingArgs)
            {
                context = (CodeContext)args[0].Value;
                contextExpression = args[0].Expression;
                args = ArrayUtils.RemoveFirst(args);
            }
            else
            {
                contextExpression = AstUtils.Constant(type.Context.SharedContext);
            }
            Debug.Assert(args.Count == callInfo.ArgumentCount + nonCountingArgs);

            TotemOverloadResolverFactory fact = new TotemOverloadResolverFactory(type.Context.Binder, contextExpression);
            var runs = methodSetups.GroupBy(mi => mi.Item2).Select(g => new { g.Key, Values = g.Select(gr => gr.Item1) });

            BindingRestrictions restrictions = target != null ? target.Restrictions : BindingRestrictions.Empty;
            foreach (var arg in args)
                restrictions = restrictions.Merge(arg.Restrictions);

            foreach (var run in runs)
            {
                BindingRestrictions runRestrictions = restrictions;
                var key = run.Key;
                var extraArgs = GetExtraArgs(key, type, target);
                var methods = run.Values.Cast<MethodBase>().ToArray();

                List<DynamicMetaObject> arguments = new List<DynamicMetaObject>(args.Count + 5); // good margin for ekstras
                List<Argument> argInfo = new List<Argument>();
                foreach (var extraArg in extraArgs)
                {
                    arguments.Add(extraArg);
                    runRestrictions = runRestrictions.Merge(extraArg.Restrictions);
                    argInfo.Add(Argument.Simple);
                }
                arguments.AddRange(args);

                int normalArgCount = callInfo.ArgumentCount - callInfo.ArgumentNames.Count;

                List<Expression> normalArgs = new List<Expression>();
                for (var i2 = 0; i2 < normalArgCount + nonCountingArgs; i2++)
                    argInfo.Add(Argument.Simple);

                for (var i2 = 0; i2 < callInfo.ArgumentNames.Count; i2++)
                    argInfo.Add(new Argument(callInfo.ArgumentNames[i2]));

                var overloadResolver = fact.CreateOverloadResolver(arguments, new CallSignature(argInfo.ToArray()), CallTypes.None);
                var bindingTarget = overloadResolver.ResolveOverload(name, methods, minLevel, maxLevel);
                if (bindingTarget.Success)
                {
                    Expression call = bindingTarget.MakeExpression();
                    if (bindingTarget.ReturnType == typeof(void))
                    {
                        call = Expression.Block(
                            call,
                            IronTotem.Parsing.Ast.ConstantExpression.Undefined
                        );
                    }

                    runRestrictions = runRestrictions.Merge(bindingTarget.RestrictedArguments.GetAllRestrictions());

                    result = new DynamicMetaObject(
                        call,
                        runRestrictions
                    );
                    return true;
                }
            }

            result = TypeError(
                binder,
                "No matching overload found"
            );
            return false;
        }
Пример #2
0
        public TotemContext(ScriptDomainManager manager, IDictionary<string, object> options)
            : base(manager)
        {
            _options = new TotemOptions(options);
            _builtinModulesDict = CreateBuiltinTable();

            TotemDictionary defaultScope = new TotemDictionary();
            ModuleContext moduleContext = new ModuleContext(defaultScope, this);
            _defaultContext = moduleContext.GlobalContext;


            TotemBinder binder = new TotemBinder(this, _defaultContext);
            _sharedOverloadResolverFactory = new TotemOverloadResolverFactory(binder, Expression.Constant(_defaultContext));
            _binder = binder;

            if (DefaultContext._default == null)
            {
                DefaultContext.InitializeDefaults(_defaultContext);
            }

            RecursionLimit = _options.RecursionLimit;

            InitializeBuiltins();
        }