예제 #1
0
		void DefineAsyncMethods (CallingConventions cc, TypeExpression returnType)
		{
			var iasync_result = Module.PredefinedTypes.IAsyncResult;
			var async_callback = Module.PredefinedTypes.AsyncCallback;

			//
			// It's ok when async types don't exist, the delegate will have Invoke method only
			//
			if (!iasync_result.Define () || !async_callback.Define ())
				return;

			//
			// BeginInvoke
			//
			ParametersCompiled async_parameters;
			if (Parameters.Count == 0) {
				async_parameters = ParametersCompiled.EmptyReadOnlyParameters;
			} else {
				var compiled = new Parameter[Parameters.Count];
				for (int i = 0; i < compiled.Length; ++i) {
					var p = parameters[i];
					compiled[i] = new Parameter (new TypeExpression (parameters.Types[i], Location),
						p.Name,
						p.ModFlags & Parameter.Modifier.RefOutMask,
						p.OptAttributes == null ? null : p.OptAttributes.Clone (), Location);
				}

				async_parameters = new ParametersCompiled (compiled);
			}

			async_parameters = ParametersCompiled.MergeGenerated (Compiler, async_parameters, false,
				new Parameter[] {
					new Parameter (new TypeExpression (async_callback.TypeSpec, Location), "callback", Parameter.Modifier.NONE, null, Location),
					new Parameter (new TypeExpression (Compiler.BuiltinTypes.Object, Location), "object", Parameter.Modifier.NONE, null, Location)
				},
				new [] {
					async_callback.TypeSpec,
					Compiler.BuiltinTypes.Object
				}
			);

			BeginInvokeBuilder = new Method (this,
				new TypeExpression (iasync_result.TypeSpec, Location), MethodModifiers,
				new MemberName ("BeginInvoke"), async_parameters, null);
			BeginInvokeBuilder.Define ();

			//
			// EndInvoke is a bit more interesting, all the parameters labeled as
			// out or ref have to be duplicated here.
			//

			//
			// Define parameters, and count out/ref parameters
			//
			ParametersCompiled end_parameters;
			int out_params = 0;

			foreach (Parameter p in Parameters.FixedParameters) {
				if ((p.ModFlags & Parameter.Modifier.RefOutMask) != 0)
					++out_params;
			}

			if (out_params > 0) {
				Parameter[] end_params = new Parameter[out_params];

				int param = 0;
				for (int i = 0; i < Parameters.FixedParameters.Length; ++i) {
					Parameter p = parameters [i];
					if ((p.ModFlags & Parameter.Modifier.RefOutMask) == 0)
						continue;

					end_params [param++] = new Parameter (new TypeExpression (p.Type, Location),
						p.Name,
						p.ModFlags & Parameter.Modifier.RefOutMask,
						p.OptAttributes == null ? null : p.OptAttributes.Clone (), Location);
				}

				end_parameters = new ParametersCompiled (end_params);
			} else {
				end_parameters = ParametersCompiled.EmptyReadOnlyParameters;
			}

			end_parameters = ParametersCompiled.MergeGenerated (Compiler, end_parameters, false,
				new Parameter (
					new TypeExpression (iasync_result.TypeSpec, Location),
					"result", Parameter.Modifier.NONE, null, Location),
				iasync_result.TypeSpec);

			//
			// Create method, define parameters, register parameters with type system
			//
			EndInvokeBuilder = new Method (this, returnType, MethodModifiers, new MemberName ("EndInvoke"), end_parameters, null);
			EndInvokeBuilder.Define ();
		}
예제 #2
0
		protected void EmitCall (EmitContext ec, Expression binder, Arguments arguments, bool isStatement)
		{
			//
			// This method generates all internal infrastructure for a dynamic call. The
			// reason why it's quite complicated is the mixture of dynamic and anonymous
			// methods. Dynamic itself requires a temporary class (ContainerX) and anonymous
			// methods can generate temporary storey as well (AnonStorey). Handling MVAR
			// type parameters rewrite is non-trivial in such case as there are various
			// combinations possible therefore the mutator is not straightforward. Secondly
			// we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit
			// correct Site field type and its access from EmitContext.
			//

			int dyn_args_count = arguments == null ? 0 : arguments.Count;
			int default_args = isStatement ? 1 : 2;
			var module = ec.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);

			TypeExpression[] targs_for_instance = null;
			TypeParameterMutator mutator;

			var site_container = ec.CreateDynamicSite ();

			if (context_mvars != null) {
				TypeParameters tparam;
				TypeContainer sc = site_container;
				do {
					tparam = sc.CurrentTypeParameters;
					sc = sc.Parent;
				} while (tparam == null);

				mutator = new TypeParameterMutator (context_mvars, tparam);

				if (!ec.IsAnonymousStoreyMutateRequired) {
					targs_for_instance = new TypeExpression[targs.Length];
					targs_for_instance[0] = targs[0];
				}
			} else {
				mutator = null;
			}

			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 = ec.BuiltinTypes.Object;

				if (targs_for_instance != null)
					targs_for_instance[i + 1] = new TypeExpression (t, loc);

				if (mutator != null)
					t = t.Mutate (mutator);

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

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

				TypeExpr te = null;
				Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true);
				if (type_ns != null) {
					te = type_ns.LookupType (module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc);
				}

				if (te != null) {
					if (!isStatement) {
						var t = type;
						if (t.Kind == MemberKind.InternalCompilerType)
							t = ec.BuiltinTypes.Object;

						if (targs_for_instance != null)
							targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression (t, loc);

						if (mutator != null)
							t = t.Mutate (mutator);

						targs[targs.Length - 1] = new TypeExpression (t, loc);
					}

					del_type = new GenericTypeExpr (te.Type, new TypeArguments (targs), loc);
					if (targs_for_instance != null)
						del_type_instance_access = new GenericTypeExpr (te.Type, new TypeArguments (targs_for_instance), loc);
					else
						del_type_instance_access = del_type;
				}
			}

			//
			// Create custom delegate when no appropriate predefined delegate has been found
			//
			Delegate d;
			if (del_type == null) {
				TypeSpec rt = isStatement ? ec.BuiltinTypes.Void : 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.Containers == null ? 0 : site.Containers.Count;

				if (mutator != null)
					rt = mutator.Mutate (rt);

				for (int i = 1; i < dyn_args_count + 1; ++i) {
					p[i] = new Parameter (targs[i], "p" + i.ToString ("X"), arguments[i - 1].Modifier, null, loc);
				}

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

				d.CreateContainer ();
				d.DefineContainer ();
				d.Define ();

				site.AddTypeContainer (d);
				del_type = new TypeExpression (d.CurrentType, loc);
				if (targs_for_instance != null) {
					del_type_instance_access = null;
				} else {
					del_type_instance_access = del_type;
				}
			} else {
				d = null;
			}

			var site_type_decl = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments (del_type), loc);
			var field = site_container.CreateCallSiteField (site_type_decl, loc);
			if (field == null)
				return;

			if (del_type_instance_access == null) {
				var dt = d.CurrentType.DeclaringType.MakeGenericType (module, context_mvars.Types);
				del_type_instance_access = new TypeExpression (MemberCache.GetMember (dt, d.CurrentType), loc);
			}

			var instanceAccessExprType = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec,
				new TypeArguments (del_type_instance_access), loc);

			if (instanceAccessExprType.ResolveAsType (ec.MemberContext) == null)
				return;

			bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired;

			TypeSpec gt;
			if (inflate_using_mvar || context_mvars == null) {
				gt = site_container.CurrentType;
			} else {
				gt = site_container.CurrentType.MakeGenericType (module, context_mvars.Types);
			}

			// When site container already exists the inflated version has to be
			// updated manually to contain newly created field
			if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) {
				var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes;
				var inflator = new TypeParameterInflator (module, gt, tparams, gt.TypeArguments);
				gt.MemberCache.AddMember (field.InflateMember (inflator));
			}

			FieldExpr site_field_expr = new FieldExpr (MemberCache.GetMember (gt, field), loc);

			BlockContext bc = new BlockContext (ec.MemberContext, null, ec.BuiltinTypes.Void);

			Arguments args = new Arguments (1);
			args.Add (new Argument (binder));
			StatementExpression s = new StatementExpression (new SimpleAssign (site_field_expr, new Invocation (new MemberAccess (instanceAccessExprType, "Create"), args)));

			using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
				if (s.Resolve (bc)) {
					Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc);
					init.Emit (ec);
				}

				args = new Arguments (1 + dyn_args_count);
				args.Add (new Argument (site_field_expr));
				if (arguments != null) {
					int arg_pos = 1;
					foreach (Argument a in arguments) {
						if (a is NamedArgument) {
							// Name is not valid in this context
							args.Add (new Argument (a.Expr, a.ArgType));
						} else {
							args.Add (a);
						}

						if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
							a.Expr.Type = targs[arg_pos].Type;

						++arg_pos;
					}
				}

				Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, loc).Resolve (bc);
				if (target != null)
					target.Emit (ec);
			}
		}
예제 #3
0
		public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
			: this (name, modifiers)
		{
			this.default_value = defaultValue;
		}
예제 #4
0
		public static AnonymousTypeClass Create (TypeContainer parent, IList<AnonymousTypeParameter> parameters, Location loc)
		{
			string name = ClassNamePrefix + parent.Module.CounterAnonymousTypes++;

			ParametersCompiled all_parameters;
			TypeParameters tparams = null;
			SimpleName[] t_args;

			if (parameters.Count == 0) {
				all_parameters = ParametersCompiled.EmptyReadOnlyParameters;
				t_args = null;
			} else {
				t_args = new SimpleName[parameters.Count];
				tparams = new TypeParameters ();
				Parameter[] ctor_params = new Parameter[parameters.Count];
				for (int i = 0; i < parameters.Count; ++i) {
					AnonymousTypeParameter p = parameters[i];
					for (int ii = 0; ii < i; ++ii) {
						if (parameters[ii].Name == p.Name) {
							parent.Compiler.Report.Error (833, parameters[ii].Location,
								"`{0}': An anonymous type cannot have multiple properties with the same name",
									p.Name);

							p = new AnonymousTypeParameter (null, "$" + i.ToString (), p.Location);
							parameters[i] = p;
							break;
						}
					}

					t_args[i] = new SimpleName ("<" + p.Name + ">__T", p.Location);
					tparams.Add (new TypeParameter (i, new MemberName (t_args[i].Name, p.Location), null, null, Variance.None));
					ctor_params[i] = new Parameter (t_args[i], p.Name, Parameter.Modifier.NONE, null, p.Location);
				}

				all_parameters = new ParametersCompiled (ctor_params);
			}

			//
			// Create generic anonymous type host with generic arguments
			// named upon properties names
			//
			AnonymousTypeClass a_type = new AnonymousTypeClass (parent.Module, new MemberName (name, tparams, loc), parameters, loc);

			Constructor c = new Constructor (a_type, name, Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN,
				null, all_parameters, loc);
			c.Block = new ToplevelBlock (parent.Module.Compiler, c.ParameterInfo, loc);

			// 
			// Create fields and constructor body with field initialization
			//
			bool error = false;
			for (int i = 0; i < parameters.Count; ++i) {
				AnonymousTypeParameter p = parameters [i];

				Field f = new Field (a_type, t_args [i], Modifiers.PRIVATE | Modifiers.READONLY | Modifiers.DEBUGGER_HIDDEN,
					new MemberName ("<" + p.Name + ">", p.Location), null);

				if (!a_type.AddField (f)) {
					error = true;
					continue;
				}

				c.Block.AddStatement (new StatementExpression (
					new SimpleAssign (new MemberAccess (new This (p.Location), f.Name),
						c.Block.GetParameterReference (i, p.Location))));

				ToplevelBlock get_block = new ToplevelBlock (parent.Module.Compiler, p.Location);
				get_block.AddStatement (new Return (
					new MemberAccess (new This (p.Location), f.Name), p.Location));

				Property prop = new Property (a_type, t_args [i], Modifiers.PUBLIC,
					new MemberName (p.Name, p.Location), null);
				prop.Get = new Property.GetMethod (prop, 0, null, p.Location);
				prop.Get.Block = get_block;
				a_type.AddMember (prop);
			}

			if (error)
				return null;

			a_type.AddConstructor (c);
			return a_type;
		}
예제 #5
0
		public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, TypeSpec compilerTypes)
		{
			return MergeGenerated (ctx, userParams, checkConflicts,
				new Parameter [] { compilerParams },
				new TypeSpec [] { compilerTypes });
		}
예제 #6
0
		public void Resolve (ResolveContext rc, Parameter p)
		{
			var expr = Resolve (rc);
			if (expr == null)
				return;

			expr = Child;

			if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsDefaultStruct))) {
				rc.Report.Error (1736, Location,
					"The expression being assigned to optional parameter `{0}' must be a constant or default value",
					p.Name);

				return;
			}

			var parameter_type = p.Type;
			if (type == parameter_type)
				return;

			var res = Convert.ImplicitConversionStandard (rc, expr, parameter_type, Location);
			if (res != null) {
				if (parameter_type.IsNullableType && res is Nullable.Wrap) {
					Nullable.Wrap wrap = (Nullable.Wrap) res;
					res = wrap.Child;
					if (!(res is Constant)) {
						rc.Report.Error (1770, Location,
							"The expression being assigned to nullable optional parameter `{0}' must be default value",
							p.Name);
						return;
					}
				}

				if (!expr.IsNull && TypeSpec.IsReferenceType (parameter_type) && parameter_type.BuiltinType != BuiltinTypeSpec.Type.String) {
					rc.Report.Error (1763, Location,
						"Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
						p.Name, parameter_type.GetSignatureForError ());

					return;
				}

				this.expr = res;
				return;
			}

			rc.Report.Error (1750, Location,
				"Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'",
				type.GetSignatureForError (), parameter_type.GetSignatureForError ());
		}
예제 #7
0
void case_175()
#line 1559 "cs-parser.jay"
{
		Error_SyntaxError (yyToken);
	  	Location l = GetLocation (yyVals[0+yyTop]);
		yyVal = new Parameter (null, null, Parameter.Modifier.NONE, (Attributes) yyVals[-1+yyTop], l);
	  }
예제 #8
0
		public static ParametersCompiled CreateFullyResolved (Parameter p, TypeSpec type)
		{
			return new ParametersCompiled (new Parameter [] { p }, new TypeSpec [] { type });
		}
예제 #9
0
void case_173()
#line 1543 "cs-parser.jay"
{
		var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop];
		yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, (Parameter.Modifier) yyVals[-2+yyTop], (Attributes) yyVals[-3+yyTop], lt.Location);
		lbag.AddLocation (yyVal, parameterModifierLocation);
	  }
예제 #10
0
void case_174()
#line 1552 "cs-parser.jay"
{
		var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop];
		report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name");
		yyVal = new Parameter ((FullNamedExpression) yyVals[-3+yyTop], lt.Value, (Parameter.Modifier) yyVals[-4+yyTop], (Attributes) yyVals[-5+yyTop], lt.Location);
		lbag.AddLocation (yyVal, parameterModifierLocation);
	  }
예제 #11
0
void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
{
	report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
  		Parameter.GetModifierSignature (mod));
}
예제 #12
0
void case_654()
#line 5373 "ps-parser.jay"
{
		var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop];

		yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, (Parameter.Modifier) yyVals[-2+yyTop], null, lt.Location);
	  }
예제 #13
0
void case_208()
#line 2040 "ps-parser.jay"
{
		Error_SyntaxError (yyToken);
	  	Location l = GetLocation (yyVals[0+yyTop]);
		var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop];
		yyVal = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, GetLocation (yyVals[0+yyTop])), lt.Value, (Parameter.Modifier) yyVals[-3+yyTop], (Attributes) yyVals[-4+yyTop], l);
		lbag.AddLocation (yyVal, parameterModifierLocation);
	  }
예제 #14
0
		private ParametersCompiled ()
		{
			parameters = new Parameter [0];
			types = TypeSpec.EmptyTypes;
		}
예제 #15
0
void case_176()
#line 1568 "cs-parser.jay"
{
		Error_SyntaxError (yyToken);
	  	Location l = GetLocation (yyVals[0+yyTop]);
		yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], null, (Parameter.Modifier) yyVals[-2+yyTop], (Attributes) yyVals[-3+yyTop], l);
		lbag.AddLocation (yyVal, parameterModifierLocation);
	  }
예제 #16
0
		public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
			this (parameters)
		{
			this.has_arglist = has_arglist;
		}
예제 #17
0
void case_178()
#line 1583 "cs-parser.jay"
{
	  	--lexer.parsing_block;
		if (lang_version <= LanguageVersion.V_3) {
			FeatureIsNotAvailable (GetLocation (yyVals[-2+yyTop]), "optional parameter");
		}
		
		Parameter.Modifier mod = (Parameter.Modifier) yyVals[-5+yyTop];
		if (mod != Parameter.Modifier.NONE) {
			switch (mod) {
			case Parameter.Modifier.REF:
			case Parameter.Modifier.OUT:
				report.Error (1741, GetLocation (yyVals[-5+yyTop]), "Cannot specify a default value for the `{0}' parameter",
					Parameter.GetModifierSignature (mod));
				break;
				
			case Parameter.Modifier.This:
				report.Error (1743, GetLocation (yyVals[-5+yyTop]), "Cannot specify a default value for the `{0}' parameter",
					Parameter.GetModifierSignature (mod));
				break;
			default:
				throw new NotImplementedException (mod.ToString ());
			}
				
			mod = Parameter.Modifier.NONE;
		}
		
		if ((valid_param_mod & ParameterModifierType.DefaultValue) == 0)
			report.Error (1065, GetLocation (yyVals[-2+yyTop]), "Optional parameter is not valid in this context");
		
		var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop];
		yyVal = new Parameter ((FullNamedExpression) yyVals[-4+yyTop], lt.Value, mod, (Attributes) yyVals[-6+yyTop], lt.Location);
		lbag.AddLocation (yyVal, parameterModifierLocation, GetLocation (yyVals[-2+yyTop])); /* parameterModifierLocation should be ignored when mod == NONE*/
		
		if (yyVals[0+yyTop] != null)
			((Parameter) yyVal).DefaultValue = new DefaultParameterValueExpression ((Expression) yyVals[0+yyTop]);
	  }
예제 #18
0
		public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, TypeSpec[] types)
		{
			return new ParametersCompiled (parameters, types);
		}
예제 #19
0
void case_646()
#line 4536 "cs-parser.jay"
{
		var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop];

		yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, Parameter.Modifier.NONE, null, lt.Location);
	  }
예제 #20
0
		//
		// Use this method when you merge compiler generated parameters with user parameters
		//
		public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, TypeSpec[] compilerTypes)
		{
			Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
			userParams.FixedParameters.CopyTo(all_params, 0);

			TypeSpec [] all_types;
			if (userParams.types != null) {
				all_types = new TypeSpec [all_params.Length];
				userParams.Types.CopyTo (all_types, 0);
			} else {
				all_types = null;
			}

			int last_filled = userParams.Count;
			int index = 0;
			foreach (Parameter p in compilerParams) {
				for (int i = 0; i < last_filled; ++i) {
					while (p.Name == all_params [i].Name) {
						if (checkConflicts && i < userParams.Count) {
							ctx.Report.Error (316, userParams[i].Location,
								"The parameter name `{0}' conflicts with a compiler generated name", p.Name);
						}
						p.Name = '_' + p.Name;
					}
				}
				all_params [last_filled] = p;
				if (all_types != null)
					all_types [last_filled] = compilerTypes [index++];
				++last_filled;
			}
			
			ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
			parameters.has_params = userParams.has_params;
			return parameters;
		}
예제 #21
0
void case_1002()
#line 6844 "cs-parser.jay"
{ 
		current_container = current_type = new Class (current_container, new MemberName ("<InteractiveExpressionClass>"), Modifiers.PUBLIC, null);

		/* (ref object retval)*/
		Parameter [] mpar = new Parameter [1];
		mpar [0] = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null);

		ParametersCompiled pars = new ParametersCompiled (mpar);
		var mods = Modifiers.PUBLIC | Modifiers.STATIC;
		if (settings.Unsafe)
			mods |= Modifiers.UNSAFE;

		current_local_parameters = pars;
		Method method = new Method (
			current_type,
			new TypeExpression (compiler.BuiltinTypes.Void, Location.Null),
			mods,
			new MemberName ("Host"),
			pars,
			null /* attributes */);
			
		current_type.AddMember (method);			

		oob_stack.Push (method);
		++lexer.parsing_block;
		start_block (lexer.Location);
	  }
예제 #22
0
		public ParameterData (string name, Parameter.Modifier modifiers)
		{
			this.name = name;
			this.modifiers = modifiers;
		}
예제 #23
0
		//
		// Creates a proxy base method call inside this container for hoisted base member calls
		//
		public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
		{
			Method proxy_method;

			//
			// One proxy per base method is enough
			//
			if (hoisted_base_call_proxies == null) {
				hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
				proxy_method = null;
			} else {
				hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
			}

			if (proxy_method == null) {
				string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);

				MemberName member_name;
				TypeArguments targs = null;
				TypeSpec return_type = method.ReturnType;
				var local_param_types = method.Parameters.Types;

				if (method.IsGeneric) {
					//
					// Copy all base generic method type parameters info
					//
					var hoisted_tparams = method.GenericDefinition.TypeParameters;
					var tparams = new TypeParameters ();

					targs = new TypeArguments ();
					targs.Arguments = new TypeSpec[hoisted_tparams.Length];
					for (int i = 0; i < hoisted_tparams.Length; ++i) {
						var tp = hoisted_tparams[i];
						var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
						tparams.Add (local_tp);

						targs.Add (new SimpleName (tp.Name, Location));
						targs.Arguments[i] = local_tp.Type;
					}

					member_name = new MemberName (name, tparams, Location);

					//
					// Mutate any method type parameters from original
					// to newly created hoisted version
					//
					var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
					return_type = mutator.Mutate (return_type);
					local_param_types = mutator.Mutate (local_param_types);
				} else {
					member_name = new MemberName (name);
				}

				var base_parameters = new Parameter[method.Parameters.Count];
				for (int i = 0; i < base_parameters.Length; ++i) {
					var base_param = method.Parameters.FixedParameters[i];
					base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
						base_param.Name, base_param.ModFlags, null, Location);
					base_parameters[i].Resolve (this, i);
				}

				var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
				if (method.Parameters.HasArglist) {
					cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
					cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
				}

				// Compiler generated proxy
				proxy_method = new Method (this, new TypeExpression (return_type, Location),
					Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
					member_name, cloned_params, null);

				var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
					IsCompilerGenerated = true
				};

				var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
				mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
				if (targs != null)
					mg.SetTypeArguments (rc, targs);

				// Get all the method parameters and pass them as arguments
				var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
				Statement statement;
				if (method.ReturnType.Kind == MemberKind.Void)
					statement = new StatementExpression (real_base_call);
				else
					statement = new Return (real_base_call, Location);

				block.AddStatement (statement);
				proxy_method.Block = block;

				members.Add (proxy_method);
				proxy_method.Define ();

				hoisted_base_call_proxies.Add (method, proxy_method);
			}

			return proxy_method.Spec;
		}
예제 #24
0
		public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
		{
			return (modFlags & Parameter.Modifier.OUT) != 0 ?
				ParameterAttributes.Out : ParameterAttributes.None;
		}
예제 #25
0
		protected virtual ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type)
		{
			var delegate_parameters = Delegate.GetParameters (delegate_type);

			if (Parameters == ParametersCompiled.Undefined) {
				//
				// We provide a set of inaccessible parameters
				//
				Parameter[] fixedpars = new Parameter[delegate_parameters.Count];

				for (int i = 0; i < delegate_parameters.Count; i++) {
					Parameter.Modifier i_mod = delegate_parameters.FixedParameters [i].ModFlags;
					if ((i_mod & Parameter.Modifier.OUT) != 0) {
						if (!ec.IsInProbingMode) {
							ec.Report.Error (1688, loc,
								"Cannot convert anonymous method block without a parameter list to delegate type `{0}' because it has one or more `out' parameters",
								delegate_type.GetSignatureForError ());
						}

						return null;
					}
					fixedpars[i] = new Parameter (
						new TypeExpression (delegate_parameters.Types [i], loc), null,
						delegate_parameters.FixedParameters [i].ModFlags, null, loc);
				}

				return ParametersCompiled.CreateFullyResolved (fixedpars, delegate_parameters.Types);
			}

			if (!VerifyExplicitParameters (ec, delegate_type, delegate_parameters)) {
				return null;
			}

			return Parameters;
		}