Mono.CSharp.DynamicExpressionStatement.CreateSiteType C# (CSharp) Method

CreateSiteType() private method

private CreateSiteType ( EmitContext ec, Arguments arguments, int dyn_args_count, bool is_statement ) : Mono.CSharp.TypeExpr
ec EmitContext
arguments Arguments
dyn_args_count int
is_statement bool
return Mono.CSharp.TypeExpr
		TypeExpr CreateSiteType (EmitContext ec, Arguments arguments, int dyn_args_count, bool is_statement)
		{
			int default_args = is_statement ? 1 : 2;
			var module = ec.MemberContext.Module;

			bool has_ref_out_argument = false;
			var targs = new TypeExpression[dyn_args_count + default_args];
			targs [0] = new TypeExpression (module.PredefinedTypes.CallSite.TypeSpec, loc);
			for (int i = 0; i < dyn_args_count; ++i) {
				Argument a = arguments [i];
				if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref)
					has_ref_out_argument = true;

				var t = a.Type;

				// Convert any internal type like dynamic or null to object
				if (t.Kind == MemberKind.InternalCompilerType)
					t = TypeManager.object_type;

				targs [i + 1] = new TypeExpression (t, loc);
			}

			TypeExpr del_type = null;
			if (!has_ref_out_argument) {
				string d_name = is_statement ? "Action" : "Func";

				TypeExpr te = null;
				Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true);
				if (type_ns != null) {
					te = type_ns.LookupType (module.Compiler, d_name, dyn_args_count + default_args, true, Location.Null);
				}
			
				if (te != null) {
					if (!is_statement)
						targs [targs.Length - 1] = new TypeExpression (type, loc);

					del_type = new GenericTypeExpr (te.Type, new TypeArguments (targs), loc);
				}
			}

			//
			// Create custom delegate when no appropriate predefined one is found
			//
			if (del_type == null) {
				TypeSpec rt = is_statement ? TypeManager.void_type : type;
				Parameter[] p = new Parameter [dyn_args_count + 1];
				p[0] = new Parameter (targs [0], "p0", Parameter.Modifier.NONE, null, loc);

				var site = ec.CreateDynamicSite ();
				int index = site.Types == null ? 0 : site.Types.Count;

				if (site.Mutator != null)
					rt = site.Mutator.Mutate (rt);

				for (int i = 1; i < dyn_args_count + 1; ++i) {
					var t = targs[i];
					if (site.Mutator != null)
						t.Type = site.Mutator.Mutate (t.Type);

					p[i] = new Parameter (t, "p" + i.ToString ("X"), arguments[i - 1].Modifier, null, loc);
				}

				Delegate d = new Delegate (site.NamespaceEntry, site, new TypeExpression (rt, loc),
					Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED,
					new MemberName ("Container" + index.ToString ("X")),
					new ParametersCompiled (p), null);

				d.CreateType ();
				d.DefineType ();
				d.Define ();
				d.Emit ();

				var inflated = site.AddDelegate (d);
				del_type = new TypeExpression (inflated, loc);
			}

			TypeExpr site_type = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments (del_type), loc);
			return site_type;
		}
	}