Inheritance: AParametersCollection
		protected void CheckReservedNameConflict (string prefix, MethodSpec accessor)
		{
			string name;
			AParametersCollection parameters;
			if (accessor != null) {
				name = accessor.Name;
				parameters = accessor.Parameters;
			} else {
				name = prefix + ShortName;
				if (IsExplicitImpl)
					name = MemberName.Left + "." + name;

				if (this is Indexer) {
					parameters = ((Indexer) this).ParameterInfo;
					if (prefix[0] == 's') {
						var data = new IParameterData[parameters.Count + 1];
						Array.Copy (parameters.FixedParameters, data, data.Length - 1);
						data[data.Length - 1] = new ParameterData ("value", Parameter.Modifier.NONE);
						var types = new TypeSpec[data.Length];
						Array.Copy (parameters.Types, types, data.Length - 1);
						types[data.Length - 1] = member_type;

						parameters = new ParametersImported (data, types, false);
					}
				} else {
					if (prefix[0] == 's')
						parameters = ParametersCompiled.CreateFullyResolved (new[] { member_type });
					else
						parameters = ParametersCompiled.EmptyReadOnlyParameters;
				}
			}

			var conflict = MemberCache.FindMember (Parent.Definition,
				new MemberFilter (name, 0, MemberKind.Method, parameters, null),
				BindingRestriction.DeclaredOnly | BindingRestriction.NoAccessors);

			if (conflict != null) {
				Report.SymbolRelatedToPreviousError (conflict);
				Report.Error (82, Location, "A member `{0}' is already reserved", conflict.GetSignatureForError ());
			}
		}
Exemple #2
0
                public override bool Resolve(BlockContext ec)
                {
                    TypeExpression    storey_type_expr = new TypeExpression(host.Definition, loc);
                    List <Expression> init             = null;

                    if (host.hoisted_this != null)
                    {
                        init = new List <Expression> (host.hoisted_params == null ? 1 : host.HoistedParameters.Count + 1);
                        HoistedThis ht   = host.hoisted_this;
                        FieldExpr   from = new FieldExpr(ht.Field, loc);
                        from.InstanceExpression = CompilerGeneratedThis.Instance;
                        init.Add(new ElementInitializer(ht.Field.Name, from, loc));
                    }

                    if (host.hoisted_params != null)
                    {
                        if (init == null)
                        {
                            init = new List <Expression> (host.HoistedParameters.Count);
                        }

                        for (int i = 0; i < host.hoisted_params.Count; ++i)
                        {
                            HoistedParameter hp    = (HoistedParameter)host.hoisted_params [i];
                            HoistedParameter hp_cp = (HoistedParameter)host.hoisted_params_copy [i];

                            FieldExpr from = new FieldExpr(hp_cp.Field, loc);
                            from.InstanceExpression = CompilerGeneratedThis.Instance;

                            init.Add(new ElementInitializer(hp.Field.Name, from, loc));
                        }
                    }

                    if (init != null)
                    {
                        new_storey = new NewInitialize(storey_type_expr, null,
                                                       new CollectionOrObjectInitializers(init, loc), loc);
                    }
                    else
                    {
                        new_storey = new New(storey_type_expr, null, loc);
                    }

                    new_storey = new_storey.Resolve(ec);
                    if (new_storey != null)
                    {
                        new_storey = Convert.ImplicitConversionRequired(ec, new_storey, host_method.MemberType, loc);
                    }

                    var t = ec.Module.PredefinedTypes.Interlocked.Resolve(loc);

                    if (t != null)
                    {
                        var p = new ParametersImported(
                            new[] {
                            new ParameterData(null, Parameter.Modifier.REF),
                            new ParameterData(null, Parameter.Modifier.NONE),
                            new ParameterData(null, Parameter.Modifier.NONE)
                        },
                            new[] {
                            TypeManager.int32_type, TypeManager.int32_type, TypeManager.int32_type
                        },
                            false);
                        var f = new MemberFilter("CompareExchange", 0, MemberKind.Method, p, TypeManager.int32_type);
                        TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod(t, f, loc);
                    }

                    ec.CurrentBranching.CurrentUsageVector.Goto();
                    return(true);
                }
Exemple #3
0
		//
		// Returns null when the property is not valid C# property
		//
		public PropertySpec CreateProperty (PropertyInfo pi, TypeSpec declaringType, MethodSpec get, MethodSpec set)
		{
			Modifiers mod = 0;
			AParametersCollection param = null;
			TypeSpec type = null;
			if (get != null) {
				mod = get.Modifiers;
				param = get.Parameters;
				type = get.ReturnType;
			}

			bool is_valid_property = true;
			if (set != null) {
				if (set.ReturnType.Kind != MemberKind.Void)
					is_valid_property = false;

				var set_param_count = set.Parameters.Count - 1;

				if (set_param_count < 0) {
					set_param_count = 0;
					is_valid_property = false;
				}

				var set_type = set.Parameters.Types[set_param_count];

				if (mod == 0) {
					AParametersCollection set_based_param;

					if (set_param_count == 0) {
						set_based_param = ParametersCompiled.EmptyReadOnlyParameters;
					} else {
						//
						// Create indexer parameters based on setter method parameters (the last parameter has to be removed)
						//
						var data = new IParameterData[set_param_count];
						var types = new TypeSpec[set_param_count];
						Array.Copy (set.Parameters.FixedParameters, data, set_param_count);
						Array.Copy (set.Parameters.Types, types, set_param_count);
						set_based_param = new ParametersImported (data, types, set.Parameters.HasParams);
					}

					mod = set.Modifiers;
					param = set_based_param;
					type = set_type;
				} else {
					if (set_param_count != get.Parameters.Count)
						is_valid_property = false;

					if (get.ReturnType != set_type)
						is_valid_property = false;

					// Possible custom accessor modifiers
					if ((mod & Modifiers.AccessibilityMask) != (set.Modifiers & Modifiers.AccessibilityMask)) {
						var get_acc = mod & Modifiers.AccessibilityMask;
						if (get_acc != Modifiers.PUBLIC) {
							var set_acc = set.Modifiers & Modifiers.AccessibilityMask;
							// If the accessor modifiers are not same, do extra restriction checks
							if (get_acc != set_acc) {
								var get_restr = ModifiersExtensions.IsRestrictedModifier (get_acc, set_acc);
								var set_restr = ModifiersExtensions.IsRestrictedModifier (set_acc, get_acc);
								if (get_restr && set_restr) {
									is_valid_property = false; // Neither is more restrictive
								}

								if (get_restr) {
									mod &= ~Modifiers.AccessibilityMask;
									mod |= set_acc;
								}
							}
						}
					}
				}
			}

			PropertySpec spec = null;
			if (!param.IsEmpty) {
				var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
				if (index_name == null) {
					is_valid_property = false;
				} else {
					if (get != null) {
						if (get.IsStatic)
							is_valid_property = false;
						if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
							is_valid_property = false;
					}
					if (set != null) {
						if (set.IsStatic)
							is_valid_property = false;
						if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
							is_valid_property = false;
					}
				}

				if (is_valid_property)
					spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod);
			}

			if (spec == null)
				spec = new PropertySpec (MemberKind.Property, declaringType, new ImportedMemberDefinition (pi, type, this), type, pi, mod);

			if (!is_valid_property) {
				spec.IsNotCSharpCompatible = true;
				return spec;
			}

			if (set != null)
				spec.Set = set;
			if (get != null)
				spec.Get = get;

			return spec;
		}
Exemple #4
0
        protected override bool DoDefineMembers()
        {
            if (IsGeneric)
            {
                foreach (TypeParameter type_param in TypeParameters)
                {
                    if (!type_param.Resolve(this))
                    {
                        return(false);
                    }
                }

                foreach (TypeParameter type_param in TypeParameters)
                {
                    if (!type_param.DefineType(this))
                    {
                        return(false);
                    }
                }
            }

            member_cache = new MemberCache(TypeManager.multicast_delegate_type, this);

            // FIXME: POSSIBLY make this static, as it is always constant
            //
            Type [] const_arg_types = new Type [2];
            const_arg_types [0] = TypeManager.object_type;
            const_arg_types [1] = TypeManager.intptr_type;

            const MethodAttributes ctor_mattr = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName |
                                                MethodAttributes.HideBySig | MethodAttributes.Public;

            ConstructorBuilder = TypeBuilder.DefineConstructor(ctor_mattr,
                                                               CallingConventions.Standard,
                                                               const_arg_types);

            ConstructorBuilder.DefineParameter(1, ParameterAttributes.None, "object");
            ConstructorBuilder.DefineParameter(2, ParameterAttributes.None, "method");
            //
            // HACK because System.Reflection.Emit is lame
            //
            IParameterData [] fixed_pars = new IParameterData [] {
                new ParameterData("object", Parameter.Modifier.NONE),
                new ParameterData("method", Parameter.Modifier.NONE)
            };

            AParametersCollection const_parameters = new ParametersImported(
                fixed_pars,
                new Type[] { TypeManager.object_type, TypeManager.intptr_type });

            TypeManager.RegisterMethod(ConstructorBuilder, const_parameters);
            member_cache.AddMember(ConstructorBuilder, this);

            ConstructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime);

            //
            // Here the various methods like Invoke, BeginInvoke etc are defined
            //
            // First, call the `out of band' special method for
            // defining recursively any types we need:

            if (!Parameters.Resolve(this))
            {
                return(false);
            }

            //
            // Invoke method
            //

            // Check accessibility
            foreach (Type partype in Parameters.Types)
            {
                if (!IsAccessibleAs(partype))
                {
                    Report.SymbolRelatedToPreviousError(partype);
                    Report.Error(59, Location,
                                 "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'",
                                 TypeManager.CSharpName(partype),
                                 GetSignatureForError());
                    return(false);
                }
            }

            ReturnType = ReturnType.ResolveAsTypeTerminal(this, false);
            if (ReturnType == null)
            {
                return(false);
            }

            ret_type = ReturnType.Type;

            if (!IsAccessibleAs(ret_type))
            {
                Report.SymbolRelatedToPreviousError(ret_type);
                Report.Error(58, Location,
                             "Inconsistent accessibility: return type `" +
                             TypeManager.CSharpName(ret_type) + "' is less " +
                             "accessible than delegate `" + GetSignatureForError() + "'");
                return(false);
            }

            CheckProtectedModifier();

            if (RootContext.StdLib && TypeManager.IsSpecialType(ret_type))
            {
                Method.Error1599(Location, ret_type, Report);
                return(false);
            }

            TypeManager.CheckTypeVariance(ret_type, Variance.Covariant, this);

            //
            // We don't have to check any others because they are all
            // guaranteed to be accessible - they are standard types.
            //

            CallingConventions cc = Parameters.CallingConvention;

            InvokeBuilder = TypeBuilder.DefineMethod("Invoke",
                                                     mattr,
                                                     cc,
                                                     ret_type,
                                                     Parameters.GetEmitTypes());

            InvokeBuilder.SetImplementationFlags(MethodImplAttributes.Runtime);

            TypeManager.RegisterMethod(InvokeBuilder, Parameters);
            member_cache.AddMember(InvokeBuilder, this);

            //
            // Don't emit async method for compiler generated delegates (e.g. dynamic site containers)
            //
            if (TypeManager.iasyncresult_type != null && TypeManager.asynccallback_type != null && !IsCompilerGenerated)
            {
                DefineAsyncMethods(cc);
            }

            return(true);
        }
Exemple #5
0
				public override bool Resolve (BlockContext ec)
				{
					TypeExpression storey_type_expr = new TypeExpression (host.Definition, loc);
					List<Expression> init = null;
					if (host.hoisted_this != null) {
						init = new List<Expression> (host.hoisted_params == null ? 1 : host.HoistedParameters.Count + 1);
						HoistedThis ht = host.hoisted_this;
						FieldExpr from = new FieldExpr (ht.Field, loc);
						from.InstanceExpression = CompilerGeneratedThis.Instance;
						init.Add (new ElementInitializer (ht.Field.Name, from, loc));
					}

					if (host.hoisted_params != null) {
						if (init == null)
							init = new List<Expression> (host.HoistedParameters.Count);

						for (int i = 0; i < host.hoisted_params.Count; ++i) {
							HoistedParameter hp = (HoistedParameter) host.hoisted_params [i];
							HoistedParameter hp_cp = (HoistedParameter) host.hoisted_params_copy [i];

							FieldExpr from = new FieldExpr (hp_cp.Field, loc);
							from.InstanceExpression = CompilerGeneratedThis.Instance;

							init.Add (new ElementInitializer (hp.Field.Name, from, loc));
						}
					}

					if (init != null) {
						new_storey = new NewInitialize (storey_type_expr, null,
							new CollectionOrObjectInitializers (init, loc), loc);
					} else {
						new_storey = new New (storey_type_expr, null, loc);
					}

					new_storey = new_storey.Resolve (ec);
					if (new_storey != null)
						new_storey = Convert.ImplicitConversionRequired (ec, new_storey, host_method.MemberType, loc);

					if (TypeManager.int_interlocked_compare_exchange == null) {
						TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Interlocked", MemberKind.Class, true);
						if (t != null) {
							var p = new ParametersImported (
								new[] {
									new ParameterData (null, Parameter.Modifier.REF),
									new ParameterData (null, Parameter.Modifier.NONE),
									new ParameterData (null, Parameter.Modifier.NONE)
								},
								new[] {
									TypeManager.int32_type, TypeManager.int32_type, TypeManager.int32_type
								},
								false);
							var f = new MemberFilter ("CompareExchange", 0, MemberKind.Method, p, TypeManager.int32_type);
							TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (t, f, loc);
						}
					}

					ec.CurrentBranching.CurrentUsageVector.Goto ();
					return true;
				}
            void FabricateBodyStatement()
            {
                var cas = TypeManager.gen_interlocked_compare_exchange;
                if (cas == null) {
                    var t = Module.PredefinedTypes.Interlocked.Resolve (Location);
                    if (t == null)
                        return;

                    var p = new ParametersImported (
                        new[] {
                                new ParameterData (null, Parameter.Modifier.REF),
                                new ParameterData (null, Parameter.Modifier.NONE),
                                new ParameterData (null, Parameter.Modifier.NONE)
                            },
                        new[] {
                                new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
                                new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
                                new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
                            }, false);

                    var filter = new MemberFilter ("CompareExchange", 1, MemberKind.Method, p, null);
                    cas = TypeManager.gen_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (t, filter, Location);
                }

                //
                // Delegate obj1 = backing_field
                // do {
                //   Delegate obj2 = obj1;
                //   obj1 =	Interlocked.CompareExchange (ref backing_field, Delegate.Combine|Remove(obj2, value), obj1);
                // } while (obj1 != obj2)
                //

                var field_info = ((EventField) method).backing_field;
                FieldExpr f_expr = new FieldExpr (field_info, Location);
                if (!IsStatic)
                    f_expr.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location);

                var obj1 = LocalVariable.CreateCompilerGenerated (field_info.MemberType, block, Location);
                var obj2 = LocalVariable.CreateCompilerGenerated (field_info.MemberType, block, Location);

                block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (obj1, Location), f_expr)));

                var cond = new BooleanExpression (new Binary (Binary.Operator.Inequality,
                    new LocalVariableReference (obj1, Location), new LocalVariableReference (obj2, Location), Location));

                var body = new ExplicitBlock (block, Location, Location);
                block.AddStatement (new Do (body, cond, Location));

                body.AddStatement (new StatementExpression (
                    new SimpleAssign (new LocalVariableReference (obj2, Location), new LocalVariableReference (obj1, Location))));

                var args_oper = new Arguments (2);
                args_oper.Add (new Argument (new LocalVariableReference (obj2, Location)));
                args_oper.Add (new Argument (block.GetParameterReference (0, Location)));

                var args = new Arguments (3);
                args.Add (new Argument (f_expr, Argument.AType.Ref));
                args.Add (new Argument (new Cast (
                    new TypeExpression (field_info.MemberType, Location),
                    new Invocation (MethodGroupExpr.CreatePredefined (Operation, Operation.DeclaringType, Location), args_oper),
                    Location)));
                args.Add (new Argument (new LocalVariableReference (obj1, Location)));

                body.AddStatement (new StatementExpression (new SimpleAssign (
                    new LocalVariableReference (obj1, Location),
                    new Invocation (MethodGroupExpr.CreatePredefined (cas, cas.DeclaringType, Location), args))));
            }
Exemple #7
0
        void EmitOnCompleted(EmitContext ec, Expression awaiter, bool unsafeVersion)
        {
            var pm = Module.PredefinedMembers;
            PredefinedMember <MethodSpec> predefined;
            bool has_task_return_type = false;

            if (return_type.Kind == MemberKind.Void)
            {
                predefined = unsafeVersion ? pm.AsyncVoidMethodBuilderOnCompletedUnsafe : pm.AsyncVoidMethodBuilderOnCompleted;
            }
            else if (return_type == Module.PredefinedTypes.Task.TypeSpec)
            {
                predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderOnCompletedUnsafe : pm.AsyncTaskMethodBuilderOnCompleted;
            }
            else if (return_type.IsGenericTask)
            {
                predefined           = unsafeVersion ? pm.AsyncTaskMethodBuilderGenericOnCompletedUnsafe : pm.AsyncTaskMethodBuilderGenericOnCompleted;
                has_task_return_type = true;
            }
            else
            {
                var parameters = new ParametersImported(
                    new [] {
                    new ParameterData(null, Parameter.Modifier.REF),
                    new ParameterData(null, Parameter.Modifier.REF)
                },
                    new [] {
                    new TypeParameterSpec(0, null, SpecialConstraint.None, Variance.None, null),
                    new TypeParameterSpec(1, null, SpecialConstraint.None, Variance.None, null)
                }, false);

                var on_completed_sign = unsafeVersion ?
                                        MemberFilter.Method("AwaitUnsafeOnCompleted", 2, parameters, Compiler.BuiltinTypes.Void) :
                                        MemberFilter.Method("AwaitOnCompleted", 2, parameters, Compiler.BuiltinTypes.Void);

                predefined           = new PredefinedMember <MethodSpec> (Module, return_type.MemberDefinition.GetAsyncMethodBuilder(), on_completed_sign);
                has_task_return_type = return_type.IsGeneric;
            }

            var on_completed = predefined.Resolve(Location);

            if (on_completed == null)
            {
                return;
            }

            if (has_task_return_type)
            {
                on_completed = MemberCache.GetMember <MethodSpec> (set_result.DeclaringType, on_completed);
            }

            on_completed = on_completed.MakeGenericMethod(this, awaiter.Type, ec.CurrentType);

            var mg = MethodGroupExpr.CreatePredefined(on_completed, on_completed.DeclaringType, Location);

            mg.InstanceExpression = new FieldExpr(builder, Location)
            {
                InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, Location)
            };

            var args = new Arguments(2);

            args.Add(new Argument(awaiter, Argument.AType.Ref));
            args.Add(new Argument(new CompilerGeneratedThis(CurrentType, Location), Argument.AType.Ref));
            using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) {
                mg.EmitCall(ec, args, true);
            }
        }
 		public override bool Define ()
		{
			if (IsGeneric) {
				foreach (TypeParameter type_param in TypeParameters) {
					if (!type_param.Resolve (this))
						return false;
				}

				foreach (TypeParameter type_param in TypeParameters) {
					if (!type_param.DefineType (this))
						return false;
				}
			}

			member_cache = new MemberCache (TypeManager.multicast_delegate_type, this);

			// FIXME: POSSIBLY make this static, as it is always constant
			//
			Type [] const_arg_types = new Type [2];
			const_arg_types [0] = TypeManager.object_type;
			const_arg_types [1] = TypeManager.intptr_type;

			const MethodAttributes ctor_mattr = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName |
				MethodAttributes.HideBySig | MethodAttributes.Public;

			ConstructorBuilder = TypeBuilder.DefineConstructor (ctor_mattr,
									    CallingConventions.Standard,
									    const_arg_types);

			ConstructorBuilder.DefineParameter (1, ParameterAttributes.None, "object");
			ConstructorBuilder.DefineParameter (2, ParameterAttributes.None, "method");
			//
			// HACK because System.Reflection.Emit is lame
			//
			IParameterData [] fixed_pars = new IParameterData [] {
				new ParameterData ("object", Parameter.Modifier.NONE),
				new ParameterData ("method", Parameter.Modifier.NONE)
			};

			AParametersCollection const_parameters = new ParametersImported (
				fixed_pars,
				new Type[] { TypeManager.object_type, TypeManager.intptr_type });
			
			TypeManager.RegisterMethod (ConstructorBuilder, const_parameters);
			member_cache.AddMember (ConstructorBuilder, this);
			
			ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);

			//
			// Here the various methods like Invoke, BeginInvoke etc are defined
			//
			// First, call the `out of band' special method for
			// defining recursively any types we need:
			
			if (!Parameters.Resolve (this))
				return false;

			//
			// Invoke method
			//

			// Check accessibility
			foreach (Type partype in Parameters.Types){
				if (!IsAccessibleAs (partype)) {
					Report.SymbolRelatedToPreviousError (partype);
					Report.Error (59, Location,
						      "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'",
						      TypeManager.CSharpName (partype),
						      GetSignatureForError ());
					return false;
				}
			}
			
			ReturnType = ReturnType.ResolveAsTypeTerminal (this, false);
			if (ReturnType == null)
				return false;

			ret_type = ReturnType.Type;
            
			if (!IsAccessibleAs (ret_type)) {
				Report.SymbolRelatedToPreviousError (ret_type);
				Report.Error (58, Location,
					      "Inconsistent accessibility: return type `" +
					      TypeManager.CSharpName (ret_type) + "' is less " +
					      "accessible than delegate `" + GetSignatureForError () + "'");
				return false;
			}

			CheckProtectedModifier ();

			if (RootContext.StdLib && TypeManager.IsSpecialType (ret_type)) {
				Method.Error1599 (Location, ret_type, Report);
				return false;
			}

			TypeManager.CheckTypeVariance (ret_type, Variance.Covariant, this);

			//
			// We don't have to check any others because they are all
			// guaranteed to be accessible - they are standard types.
			//
			
  			CallingConventions cc = Parameters.CallingConvention;

 			InvokeBuilder = TypeBuilder.DefineMethod ("Invoke", 
 								  mattr,		     
 								  cc,
 								  ret_type,		     
 								  Parameters.GetEmitTypes ());
			
			InvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);

			TypeManager.RegisterMethod (InvokeBuilder, Parameters);
			member_cache.AddMember (InvokeBuilder, this);

			//
			// Don't emit async method for compiler generated delegates (e.g. dynamic site containers)
			//
			if (TypeManager.iasyncresult_type != null && TypeManager.asynccallback_type != null && !IsCompilerGenerated) {
				DefineAsyncMethods (cc);
			}

			return true;
		}