コード例 #1
0
ファイル: ClrGenerators.cs プロジェクト: traviolia/IronScheme
        // (clr-new type arg1 ... )
        public override Expression Generate(object args, CodeBlock cb)
        {
            Type   t;
            string type;
            bool   inferred;

            object rtype = Builtins.First(args);

            ExtractTypeInfo(rtype, out t, out type, out inferred);

            if (t == null)
            {
                ClrSyntaxError("clr-new", "type not found", type);
            }

            Expression[] arguments = GetAstListNoCast(Builtins.Cdr(args) as Cons, cb);

            List <MethodBase> candidates = new List <MethodBase>();

            foreach (ConstructorInfo c in t.GetConstructors())
            {
                bool add = true;

                foreach (var pi in c.GetParameters())
                {
                    if (pi.ParameterType.IsPointer)
                    {
                        add = false;
                        break;
                    }
                }

                if (add)
                {
                    candidates.Add(c);
                }
            }

            if (t.IsValueType && arguments.Length == 0)
            {
                // create default valuetype here
                return(Ast.DefaultValueType(t));
            }

            Type[] types = new Type[arguments.Length];

            for (int i = 0; i < types.Length; i++)
            {
                types[i] = arguments[i].Type;
            }

            CallType ct = CallType.None;

            MethodBinder mb = MethodBinder.MakeBinder(Binder, "ctr", candidates, BinderType.Normal);

            MethodCandidate mc = mb.MakeBindingTarget(ct, types);

            if (mc == null)
            {
                types = new Type[arguments.Length];

                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = typeof(object);
                }

                if (ct == CallType.ImplicitInstance)
                {
                    types = ArrayUtils.Insert(t, types);
                }

                mc = mb.MakeBindingTarget(ct, types);
            }

            ConstructorInfo ci = null;

            if (mc == null && candidates.Count > 0)
            {
                foreach (ConstructorInfo c in candidates)
                {
                    if (c.GetParameters().Length == arguments.Length)
                    {
                        ci = c;
                        break; // tough luck for now
                    }
                }
            }
            else
            {
                ci = mc.Target.Method as ConstructorInfo;
            }

            if (ci != null)
            {
                ParameterInfo[] pars = ci.GetParameters();
                for (int i = 0; i < arguments.Length; i++)
                {
                    Type tt = pars[i].ParameterType;
                    arguments[i] = ConvertToHelper(tt, arguments[i]);
                }

                Expression r = Ast.New(ci, arguments);
                return(r);
            }

            ClrSyntaxError("clr-new", "constructor could not be resolved on type: " + type, args);

            return(null);
        }