Пример #1
0
 public void ImplementMethod(MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one, out MethodSpec ambiguousCandidate, ref bool optional)
 {
     InterfaceMethod(name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll, out ambiguousCandidate, ref optional);
 }
Пример #2
0
		/// <summary>
		///   Whether the specified method is an interface method implementation
		/// </summary>
		public MethodSpec IsInterfaceMethod (MemberName name, TypeSpec ifaceType, MethodData method, out MethodSpec ambiguousCandidate, ref bool optional)
		{
			return InterfaceMethod (name, ifaceType, method, Operation.Lookup, out ambiguousCandidate, ref optional);
		}
Пример #3
0
		/// <remarks>
		///   If a method in Type `t' (or null to look in all interfaces
		///   and the base abstract class) with name `Name', return type `ret_type' and
		///   arguments `args' implements an interface, this method will
		///   return the MethodInfo that this method implements.
		///
		///   If `name' is null, we operate solely on the method's signature.  This is for
		///   instance used when implementing indexers.
		///
		///   The `Operation op' controls whether to lookup, clear the pending bit, or clear
		///   all the methods with the given signature.
		///
		///   The `MethodInfo need_proxy' is used when we're implementing an interface's
		///   indexer in a class.  If the new indexer's IndexerName does not match the one
		///   that was used in the interface, then we always need to create a proxy for it.
		///
		/// </remarks>
		public MethodSpec InterfaceMethod (MemberName name, TypeSpec iType, MethodData method, Operation op, out MethodSpec ambiguousCandidate, ref bool optional)
		{
			ambiguousCandidate = null;

			if (pending_implementations == null)
				return null;

			TypeSpec ret_type = method.method.ReturnType;
			ParametersCompiled args = method.method.ParameterInfo;
			bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod;
			MethodSpec m;

			foreach (TypeAndMethods tm in pending_implementations){
				if (!(iType == null || tm.type == iType))
					continue;

				int method_count = tm.methods.Count;
				for (int i = 0; i < method_count; i++){
					m = tm.methods [i];

					if (m == null)
						continue;

					if (is_indexer) {
						if (!m.IsAccessor || m.Parameters.IsEmpty)
							continue;
					} else {
						if (name.Name != m.Name)
							continue;

						if (m.Arity != name.Arity)
							continue;
					}

					if (!TypeSpecComparer.Override.IsEqual (m.Parameters, args))
						continue;

					if (!TypeSpecComparer.Override.IsEqual (m.ReturnType, ret_type)) {
						tm.found[i] = method;
						continue;
					}

					//
					// `need_proxy' is not null when we're implementing an
					// interface indexer and this is Clear(One/All) operation.
					//
					// If `name' is null, then we do a match solely based on the
					// signature and not on the name (this is done in the Lookup
					// for an interface indexer).
					//
					if (op != Operation.Lookup) {
						if (m.IsAccessor != method.method.IsAccessor)
							continue;

						// If `t != null', then this is an explicitly interface
						// implementation and we can always clear the method.
						// `need_proxy' is not null if we're implementing an
						// interface indexer.  In this case, we need to create
						// a proxy if the implementation's IndexerName doesn't
						// match the IndexerName in the interface.
						if (m.DeclaringType.IsInterface && iType == null && name.Name != m.Name) {	// TODO: This is very expensive comparison
							tm.need_proxy[i] = method.method.Spec;
						} else {
							tm.methods[i] = null;
						}
					} else {
						tm.found [i] = method;
						optional = tm.optional;
					}

					if (op == Operation.Lookup && name.ExplicitInterface != null && ambiguousCandidate == null) {
						ambiguousCandidate = m;
						continue;
					}

					//
					// Lookups and ClearOne return
					//
					if (op != Operation.ClearAll)
						return m;
				}

				// If a specific type was requested, we can stop now.
				if (tm.type == iType)
					break;
			}

			m = ambiguousCandidate;
			ambiguousCandidate = null;
			return m;
		}
Пример #4
0
			public virtual MethodBuilder Define (DeclSpace parent)
			{
				parameters.Resolve (this);

				method_data = new MethodData (method, method.ModFlags,
					method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);

				if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
					return null;

				MethodBuilder mb = method_data.MethodBuilder;
				ParameterInfo.ApplyAttributes (mb);
				Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags);
				Spec.IsAccessor = true;

				return mb;
			}
Пример #5
0
			public virtual MethodBuilder Define (TypeContainer parent)
			{
				// Fill in already resolved event type to speed things up and
				// avoid confusing duplicate errors
				((Parameter) parameters.FixedParameters[0]).Type = method.member_type;
				parameters.Types = new TypeSpec[] { method.member_type };

				method_data = new MethodData (method, method.ModFlags,
					method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);

				if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
					return null;

				method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo);

				if (Compiler.Settings.WriteMetadataOnly)
					block = null;

				Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, method.ModFlags);
				Spec.IsAccessor = true;

				return method_data.MethodBuilder;
			}
Пример #6
0
 /// <summary>
 ///   Whether the specified method is an interface method implementation
 /// </summary>
 public MethodSpec IsInterfaceMethod(MemberName name, TypeSpec ifaceType, MethodData method)
 {
     return InterfaceMethod (name, ifaceType, method, Operation.Lookup);
 }
Пример #7
0
			public override void Define (TypeContainer parent)
			{
				base.Define (parent);

				Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, ModFlags);

				method_data = new MethodData (method, ModFlags, flags, this);

				method_data.Define (parent.PartialContainer, method.GetFullName (MemberName));
			}
Пример #8
0
			public virtual MethodBuilder Define (DeclSpace parent)
			{
				method_data = new MethodData (method, method.ModFlags,
					method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);

				if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
					return null;

				MethodBuilder mb = method_data.MethodBuilder;
				ParameterInfo.ApplyAttributes (mb);
				return mb;
			}
Пример #9
0
		/// <summary>
		///   Whether the specified method is an interface method implementation
		/// </summary>
		public MethodInfo IsInterfaceMethod (string name, Type ifaceType, MethodData method)
		{
			return InterfaceMethod (name, ifaceType, method, Operation.Lookup);
		}
Пример #10
0
		public override void Emit ()
		{
			if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
				PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (MethodBuilder);
			if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
				PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (MethodBuilder);

			if (TypeManager.IsDynamicType (ReturnType)) {
				return_attributes = new ReturnParameter (MethodBuilder, Location);
				return_attributes.EmitPredefined (PredefinedAttributes.Get.Dynamic, Location);
			}

			if (OptAttributes != null)
				OptAttributes.Emit ();

			if (declarative_security != null) {
				foreach (DictionaryEntry de in declarative_security) {
					MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
				}
			}

			if (MethodData != null)
				MethodData.Emit (Parent);

			base.Emit ();

			Block = null;
			MethodData = null;
		}
Пример #11
0
			public override MethodBuilder Define (DeclSpace parent)
			{
				parameters.Resolve (this);
				
				base.Define (parent);

				if (IsDummy)
					return null;

				method_data = new MethodData (method, ModFlags, flags, this);

				if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
					return null;

				return method_data.MethodBuilder;
			}
Пример #12
0
		public override bool Define ()
		{
			if (!base.Define ())
				return false;

			if (!CheckBase ())
				return false;

			if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
				//
				// Current method is turned into automatically generated
				// wrapper which creates an instance of iterator
				//
				Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
				ModFlags |= Modifiers.DEBUGGER_HIDDEN;
			}

			if (IsPartialDefinition) {
				caching_flags &= ~Flags.Excluded_Undetected;
				caching_flags |= Flags.Excluded;
				// Add to member cache only when a partial method implementation is not there
				if ((caching_flags & Flags.MethodOverloadsExist) == 0) {
					MethodBase mb = new PartialMethodDefinitionInfo (this);
					Parent.MemberCache.AddMember (mb, this);
					TypeManager.AddMethod (mb, this);
				}

				return true;
			}

			MethodData = new MethodData (
				this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);

			if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName), Report))
				return false;
					
			MethodBuilder = MethodData.MethodBuilder;

			if (TypeManager.IsGenericMethod (MethodBuilder))
				Parent.MemberCache.AddGenericMember (MethodBuilder, this);
			
			Parent.MemberCache.AddMember (MethodBuilder, this);

			return true;
		}
Пример #13
0
        /// <summary>
        ///   Verifies that any pending abstract methods or interface methods
        ///   were implemented.
        /// </summary>
        public bool VerifyPendingMethods()
        {
            int  top    = pending_implementations.Length;
            bool errors = false;
            int  i;

            for (i = 0; i < top; i++)
            {
                TypeSpec type = pending_implementations [i].type;

                bool base_implements_type = type.IsInterface &&
                                            container.BaseType != null &&
                                            container.BaseType.ImplementsInterface(type, false);

                for (int j = 0; j < pending_implementations [i].methods.Count; ++j)
                {
                    var mi = pending_implementations[i].methods[j];
                    if (mi == null)
                    {
                        continue;
                    }

                    if (type.IsInterface)
                    {
                        var need_proxy =
                            pending_implementations [i].need_proxy [j];

                        if (need_proxy != null)
                        {
                            DefineProxy(type, need_proxy, mi);
                            continue;
                        }

                        if (pending_implementations [i].optional)
                        {
                            continue;
                        }

                        MethodSpec candidate = null;
                        if (base_implements_type || BaseImplements(type, mi, out candidate))
                        {
                            continue;
                        }

                        if (candidate == null)
                        {
                            MethodData md = pending_implementations [i].found [j];
                            if (md != null)
                            {
                                candidate = md.method.Spec;
                            }
                        }

                        Report.SymbolRelatedToPreviousError(mi);
                        if (candidate != null)
                        {
                            Report.SymbolRelatedToPreviousError(candidate);
                            if (candidate.IsStatic)
                            {
                                Report.Error(736, container.Location,
                                             "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' is static",
                                             container.GetSignatureForError(), mi.GetSignatureForError(), candidate.GetSignatureForError());
                            }
                            else if ((candidate.Modifiers & Modifiers.PUBLIC) == 0)
                            {
                                Report.Error(737, container.Location,
                                             "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' in not public",
                                             container.GetSignatureForError(), mi.GetSignatureForError(), candidate.GetSignatureForError());
                            }
                            else
                            {
                                Report.Error(738, container.Location,
                                             "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' return type `{3}' does not match interface member return type `{4}'",
                                             container.GetSignatureForError(), mi.GetSignatureForError(), candidate.GetSignatureForError(),
                                             candidate.ReturnType.GetSignatureForError(), mi.ReturnType.GetSignatureForError());
                            }
                        }
                        else
                        {
                            Report.Error(535, container.Location, "`{0}' does not implement interface member `{1}'",
                                         container.GetSignatureForError(), mi.GetSignatureForError());
                        }
                    }
                    else
                    {
                        Report.SymbolRelatedToPreviousError(mi);
                        Report.Error(534, container.Location, "`{0}' does not implement inherited abstract member `{1}'",
                                     container.GetSignatureForError(), mi.GetSignatureForError());
                    }
                    errors = true;
                }
            }
            return(errors);
        }
Пример #14
0
        /// <remarks>
        ///   If a method in Type `t' (or null to look in all interfaces
        ///   and the base abstract class) with name `Name', return type `ret_type' and
        ///   arguments `args' implements an interface, this method will
        ///   return the MethodInfo that this method implements.
        ///
        ///   If `name' is null, we operate solely on the method's signature.  This is for
        ///   instance used when implementing indexers.
        ///
        ///   The `Operation op' controls whether to lookup, clear the pending bit, or clear
        ///   all the methods with the given signature.
        ///
        ///   The `MethodInfo need_proxy' is used when we're implementing an interface's
        ///   indexer in a class.  If the new indexer's IndexerName does not match the one
        ///   that was used in the interface, then we always need to create a proxy for it.
        ///
        /// </remarks>
        public MethodSpec InterfaceMethod(MemberName name, TypeSpec iType, MethodData method, Operation op, out MethodSpec ambiguousCandidate, ref bool optional)
        {
            ambiguousCandidate = null;

            if (pending_implementations == null)
            {
                return(null);
            }

            TypeSpec           ret_type = method.method.ReturnType;
            ParametersCompiled args     = method.method.ParameterInfo;
            bool       is_indexer       = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod;
            MethodSpec m;

            foreach (TypeAndMethods tm in pending_implementations)
            {
                if (!(iType == null || tm.type == iType))
                {
                    continue;
                }

                int method_count = tm.methods.Count;
                for (int i = 0; i < method_count; i++)
                {
                    m = tm.methods [i];

                    if (m == null)
                    {
                        continue;
                    }

                    if (is_indexer)
                    {
                        if (!m.IsAccessor || m.Parameters.IsEmpty)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (name.Name != m.Name)
                        {
                            continue;
                        }

                        if (m.Arity != name.Arity)
                        {
                            continue;
                        }
                    }

                    if (!TypeSpecComparer.Override.IsEqual(m.Parameters, args))
                    {
                        continue;
                    }

                    if (!TypeSpecComparer.Override.IsEqual(m.ReturnType, ret_type))
                    {
                        tm.found[i] = method;
                        continue;
                    }

                    //
                    // `need_proxy' is not null when we're implementing an
                    // interface indexer and this is Clear(One/All) operation.
                    //
                    // If `name' is null, then we do a match solely based on the
                    // signature and not on the name (this is done in the Lookup
                    // for an interface indexer).
                    //
                    if (op != Operation.Lookup)
                    {
                        if (m.IsAccessor != method.method.IsAccessor)
                        {
                            continue;
                        }

                        // If `t != null', then this is an explicitly interface
                        // implementation and we can always clear the method.
                        // `need_proxy' is not null if we're implementing an
                        // interface indexer.  In this case, we need to create
                        // a proxy if the implementation's IndexerName doesn't
                        // match the IndexerName in the interface.
                        if (m.DeclaringType.IsInterface && iType == null && name.Name != m.Name)                                // TODO: This is very expensive comparison
                        {
                            tm.need_proxy[i] = method.method.Spec;
                        }
                        else
                        {
                            tm.methods[i] = null;
                        }
                    }
                    else
                    {
                        tm.found [i] = method;
                        optional     = tm.optional;
                    }

                    if (op == Operation.Lookup && name.ExplicitInterface != null && ambiguousCandidate == null)
                    {
                        ambiguousCandidate = m;
                        continue;
                    }

                    //
                    // Lookups and ClearOne return
                    //
                    if (op != Operation.ClearAll)
                    {
                        return(m);
                    }
                }

                // If a specific type was requested, we can stop now.
                if (tm.type == iType)
                {
                    break;
                }
            }

            m = ambiguousCandidate;
            ambiguousCandidate = null;
            return(m);
        }
Пример #15
0
        public override void Emit()
        {
            if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
                PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (MethodBuilder);
            if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
                PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (MethodBuilder);

            if (ReturnType == InternalType.Dynamic) {
                return_attributes = new ReturnParameter (this, MethodBuilder, Location);
                PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
            } else {
                var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType);
                if (trans_flags != null) {
                    var pa = PredefinedAttributes.Get.DynamicTransform;
                    if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
                        return_attributes = new ReturnParameter (this, MethodBuilder, Location);
                        return_attributes.Builder.SetCustomAttribute (
                            new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
                    }
                }
            }

            if (OptAttributes != null)
                OptAttributes.Emit ();

            if (declarative_security != null) {
                foreach (var de in declarative_security) {
                    MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
                }
            }

            if (MethodData != null)
                MethodData.Emit (Parent);

            base.Emit ();

            Block = null;
            MethodData = null;
        }
Пример #16
0
		/// <remarks>
		///   If a method in Type `t' (or null to look in all interfaces
		///   and the base abstract class) with name `Name', return type `ret_type' and
		///   arguments `args' implements an interface, this method will
		///   return the MethodInfo that this method implements.
		///
		///   If `name' is null, we operate solely on the method's signature.  This is for
		///   instance used when implementing indexers.
		///
		///   The `Operation op' controls whether to lookup, clear the pending bit, or clear
		///   all the methods with the given signature.
		///
		///   The `MethodInfo need_proxy' is used when we're implementing an interface's
		///   indexer in a class.  If the new indexer's IndexerName does not match the one
		///   that was used in the interface, then we always need to create a proxy for it.
		///
		/// </remarks>
		public MethodInfo InterfaceMethod (string name, Type iType, MethodData method, Operation op)
		{
			if (pending_implementations == null)
				return null;

			Type ret_type = method.method.ReturnType;
			ParametersCompiled args = method.method.ParameterInfo;
			int arg_len = args.Count;
			bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod;

			foreach (TypeAndMethods tm in pending_implementations){
				if (!(iType == null || tm.type == iType))
					continue;

				int method_count = tm.methods.Length;
				MethodInfo m;
				for (int i = 0; i < method_count; i++){
					m = tm.methods [i];

					if (m == null)
						continue;

					//
					// Check if we have the same parameters
					//

					if (tm.args [i] == null && arg_len != 0)
						continue;
					if (tm.args [i] != null && tm.args [i].Length != arg_len)
						continue;

					string mname = TypeManager.GetMethodName (m);

					//
					// `need_proxy' is not null when we're implementing an
					// interface indexer and this is Clear(One/All) operation.
					//
					// If `name' is null, then we do a match solely based on the
					// signature and not on the name (this is done in the Lookup
					// for an interface indexer).
					//

					if (is_indexer) {
						IMethodData md = TypeManager.GetMethod (m);
						if (md != null) {
							if (!(md is Indexer.SetIndexerMethod || md is Indexer.GetIndexerMethod))
								continue;
						} else {
							if (TypeManager.GetPropertyFromAccessor (m) == null)
								continue;
						}
					} else if (name != mname) {
						continue;
					}

					int j;

					for (j = 0; j < arg_len; j++) {
						if (!TypeManager.IsEqual (tm.args [i][j], args.Types [j]))
							break;
						if (tm.mods [i][j] == args.FixedParameters [j].ModFlags)
							continue;
						// The modifiers are different, but if one of them
						// is a PARAMS modifier, and the other isn't, ignore
						// the difference.
						if (tm.mods [i][j] != Parameter.Modifier.PARAMS &&
						    args.FixedParameters [j].ModFlags != Parameter.Modifier.PARAMS)
							break;
					}
					if (j != arg_len)
						continue;

					Type rt = TypeManager.TypeToCoreType (m.ReturnType);
					if (!TypeManager.IsEqual (ret_type, rt) &&
						!(ret_type == null && rt == TypeManager.void_type) &&
						!(rt == null && ret_type == TypeManager.void_type)) {
						tm.found [i] = method;
						continue;
					}

					if (op != Operation.Lookup) {
						// If `t != null', then this is an explicitly interface
						// implementation and we can always clear the method.
						// `need_proxy' is not null if we're implementing an
						// interface indexer.  In this case, we need to create
						// a proxy if the implementation's IndexerName doesn't
						// match the IndexerName in the interface.
						if (iType == null && name != mname)
							tm.need_proxy [i] = method.MethodBuilder;
						else
							tm.methods [i] = null;
					} else {
						tm.found [i] = method;
					}

					//
					// Lookups and ClearOne return
					//
					if (op != Operation.ClearAll)
						return m;
				}

				// If a specific type was requested, we can stop now.
				if (tm.type == iType)
					return null;
			}
			return null;
		}
Пример #17
0
 public void ImplementMethod(MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one)
 {
     InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll);
 }
Пример #18
0
		//
		// Creates the type
		//
		public override bool Define (TypeContainer parent)
		{
			if (!DoDefine (parent))
				return false;

			if (!CheckBase (parent))
				return false;

			CallingConventions cc = GetCallingConvention (parent is Class);

			MethodData = new MethodData (this, null, MemberType, ParameterTypes,
						     ParameterInfo, cc, OptAttributes,
						     ModFlags, flags, true);

			if (!MethodData.Define (parent))
				return false;

			MethodBuilder = MethodData.MethodBuilder;
			
			//
			// This is used to track the Entry Point,
			//
			if (Name == "Main" &&
			    ((ModFlags & Modifiers.STATIC) != 0) && 
			    (RootContext.MainClass == null ||
			     RootContext.MainClass == parent.TypeBuilder.FullName)){
                                if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
                                        if (RootContext.EntryPoint == null) {
                                                RootContext.EntryPoint = MethodBuilder;
                                                RootContext.EntryPointLocation = Location;
                                        } else {
                                                DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
                                                DuplicateEntryPoint (MethodBuilder, Location);
                                        }
                                } else                                 	
                               	        Report28(MethodBuilder);
			}

			return true;
		}
Пример #19
0
		public override void Emit ()
		{
			if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
				Compiler.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder);
			if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
				Compiler.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder);

			if (ReturnType == InternalType.Dynamic) {
				return_attributes = new ReturnParameter (this, MethodBuilder, Location);
				Compiler.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
			} else if (ReturnType.HasDynamicElement) {
				return_attributes = new ReturnParameter (this, MethodBuilder, Location);
				Compiler.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType);
			}

			if (OptAttributes != null)
				OptAttributes.Emit ();

			if (declarative_security != null) {
				foreach (var de in declarative_security) {
					MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
				}
			}

			if (MethodData != null)
				MethodData.Emit (Parent);

			base.Emit ();

			Block = null;
			MethodData = null;
		}
Пример #20
0
		public override bool Define (TypeContainer parent)
		{
			if (!DoDefine (parent))
				return false;

			if (!CheckBase (parent))
				return false;

			flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;

			if (Get != null) {
				Type [] parameters = TypeManager.NoTypes;

				InternalParameters ip = new InternalParameters (
					parent, Parameters.EmptyReadOnlyParameters);

				GetData = new MethodData (this, "get", MemberType,
							  parameters, ip, CallingConventions.Standard,
							  Get.OptAttributes, ModFlags, flags, false);
				
				if (!GetData.Define (parent))
					return false;

				GetBuilder = GetData.MethodBuilder;
			}

			if (Set != null) {
				Type [] parameters = new Type [1];
				parameters [0] = MemberType;

				Parameter [] parms = new Parameter [1];
				parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
				InternalParameters ip = new InternalParameters (
					parent, new Parameters (parms, null, Location));

				SetData = new MethodData (this, "set", TypeManager.void_type,
							  parameters, ip, CallingConventions.Standard,
							  Set.OptAttributes, ModFlags, flags, false);

				if (!SetData.Define (parent))
					return false;

				SetBuilder = SetData.MethodBuilder;
				SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); 
			}

			// FIXME - PropertyAttributes.HasDefault ?
			
			PropertyAttributes prop_attr =
			PropertyAttributes.RTSpecialName |
			PropertyAttributes.SpecialName;

			if (!IsExplicitImpl){
				PropertyBuilder = parent.TypeBuilder.DefineProperty (
					Name, prop_attr, MemberType, null);
				
				if (Get != null)
					PropertyBuilder.SetGetMethod (GetBuilder);
				
				if (Set != null)
					PropertyBuilder.SetSetMethod (SetBuilder);

				//
				// HACK for the reasons exposed above
				//
				if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
					Report.Error (
						111, Location,
						"Class `" + parent.Name +
						"' already contains a definition for the property `" +
						Name + "'");
					return false;
				}
			}
			return true;
		}
Пример #21
0
		public override bool Define ()
		{
			if (!base.Define ())
				return false;

			if (!CheckBase ())
				return false;

			MemberKind kind;
			if (this is Operator)
				kind = MemberKind.Operator;
			else if (this is Destructor)
				kind = MemberKind.Destructor;
			else
				kind = MemberKind.Method;

			if (IsPartialDefinition) {
				caching_flags &= ~Flags.Excluded_Undetected;
				caching_flags |= Flags.Excluded;

				// Add to member cache only when a partial method implementation has not been found yet
				if ((caching_flags & Flags.PartialDefinitionExists) == 0) {
//					MethodBase mb = new PartialMethodDefinitionInfo (this);

					spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
					if (MemberName.Arity > 0) {
						spec.IsGeneric = true;

						// TODO: Have to move DefineMethod after Define (ideally to Emit)
						throw new NotImplementedException ("Generic partial methods");
					}

					Parent.MemberCache.AddMember (spec);
				}

				return true;
			}

			MethodData = new MethodData (
				this, ModFlags, flags, this, MethodBuilder, base_method);

			if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
				return false;
					
			MethodBuilder = MethodData.MethodBuilder;

			spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
			if (MemberName.Arity > 0)
				spec.IsGeneric = true;
			
			Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);

			return true;
		}
Пример #22
0
		public override bool Define (TypeContainer parent)
		{
			EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;

			if (!DoDefine (parent))
				return false;

			if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
				Report.Error (74, Location, "'" + parent.Name + "." + Name +
					      "': abstract event can not have an initializer");
				return false;
			}
			
			if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
				Report.Error (66, Location, "'" + parent.Name + "." + Name +
					      "' : event must be of a delegate type");
				return false;
			}

			Type [] parameter_types = new Type [1];
			parameter_types [0] = MemberType;

			Parameter [] parms = new Parameter [1];
			parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
			InternalParameters ip = new InternalParameters (
				parent, new Parameters (parms, null, Location)); 

			if (!CheckBase (parent))
				return false;

			//
			// Now define the accessors
			//
			AddData = new MethodData (this, "add", TypeManager.void_type,
						  parameter_types, ip, CallingConventions.Standard,
						  (Add != null) ? Add.OptAttributes : null,
						  ModFlags, flags, false);

			if (!AddData.Define (parent))
				return false;

			AddBuilder = AddData.MethodBuilder;
			AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");

			RemoveData = new MethodData (this, "remove", TypeManager.void_type,
						     parameter_types, ip, CallingConventions.Standard,
						     (Remove != null) ? Remove.OptAttributes : null,
						     ModFlags, flags, false);

			if (!RemoveData.Define (parent))
				return false;

			RemoveBuilder = RemoveData.MethodBuilder;
			RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");

			if (!IsExplicitImpl){
				EventBuilder = new MyEventBuilder (this,
					parent.TypeBuilder, Name, e_attr, MemberType);
					
				if (Add == null && Remove == null) {
					FieldBuilder = parent.TypeBuilder.DefineField (
						Name, MemberType,
						FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
					TypeManager.RegisterPrivateFieldOfEvent (
						(EventInfo) EventBuilder, FieldBuilder);
					TypeManager.RegisterFieldBase (FieldBuilder, this);
				}
			
				EventBuilder.SetAddOnMethod (AddBuilder);
				EventBuilder.SetRemoveOnMethod (RemoveBuilder);

				if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
					Report.Error (111, Location,
						      "Class `" + parent.Name +
						      "' already contains a definition for the event `" +
						      Name + "'");
					return false;
				}
			}
			
			return true;
		}
Пример #23
0
			public override MethodBuilder Define (DeclSpace parent)
			{
				parameters.Resolve (this);
				
				base.Define (parent);

				Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);

				method_data = new MethodData (method, ModFlags, flags, this);

				if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
					return null;

				Spec.SetMetaInfo (method_data.MethodBuilder);

				return method_data.MethodBuilder;
			}
Пример #24
0
		public override bool Define (TypeContainer parent)
		{
			PropertyAttributes prop_attr =
				PropertyAttributes.RTSpecialName |
				PropertyAttributes.SpecialName;
			
			if (!DoDefine (parent))
				return false;

			IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
			if (IndexerName == null)
				IndexerName = "Item";
			else if (IsExplicitImpl)
				Report.Error (592, Location,
					      "Attribute 'IndexerName' is not valid on this declaration " +
					      "type. It is valid on `property' declarations only.");

			ShortName = IndexerName;
			if (IsExplicitImpl) {
				InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
				Name = InterfaceType.FullName + "." + IndexerName;
			} else {
				InterfaceIndexerName = IndexerName;
				Name = ShortName;
			}

			if (!CheckBase (parent))
				return false;

			flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
			if (Get != null){
                                InternalParameters ip = new InternalParameters (parent, Parameters);

				GetData = new MethodData (this, "get", MemberType,
							  ParameterTypes, ip, CallingConventions.Standard,
							  Get.OptAttributes, ModFlags, flags, false);

				if (!GetData.Define (parent))
					return false;

				GetBuilder = GetData.MethodBuilder;
			}
			
			if (Set != null){
				int top = ParameterTypes.Length;
				Type [] set_pars = new Type [top + 1];
				ParameterTypes.CopyTo (set_pars, 0);
				set_pars [top] = MemberType;

				Parameter [] fixed_parms = Parameters.FixedParameters;

				if (fixed_parms == null){
					throw new Exception ("We currently do not support only array arguments in an indexer");
					// BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
					// BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
					//
					// Here is the problem: the `value' parameter has
					// to come *after* the array parameter in the declaration
					// like this:
					// X (object [] x, Type value)
					// .param [0]
					//
					// BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
					// BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
					
				}
				
				Parameter [] tmp = new Parameter [fixed_parms.Length + 1];


				fixed_parms.CopyTo (tmp, 0);
				tmp [fixed_parms.Length] = new Parameter (
					Type, "value", Parameter.Modifier.NONE, null);

				Parameters set_formal_params = new Parameters (tmp, null, Location);
				
				InternalParameters ip = new InternalParameters (parent, set_formal_params);

				SetData = new MethodData (this, "set", TypeManager.void_type,
							  set_pars, ip, CallingConventions.Standard,
							  Set.OptAttributes, ModFlags, flags, false);

				if (!SetData.Define (parent))
					return false;

				SetBuilder = SetData.MethodBuilder;
			}

			//
			// Now name the parameters
			//
			Parameter [] p = Parameters.FixedParameters;
			if (p != null) {
				int i;
				
				for (i = 0; i < p.Length; ++i) {
					if (Get != null)
						GetBuilder.DefineParameter (
							i + 1, p [i].Attributes, p [i].Name);

					if (Set != null)
						SetBuilder.DefineParameter (
							i + 1, p [i].Attributes, p [i].Name);
				}

				if (Set != null)
					SetBuilder.DefineParameter (
						i + 1, ParameterAttributes.None, "value");
					
				if (i != ParameterTypes.Length) {
					Parameter array_param = Parameters.ArrayParameter;
					SetBuilder.DefineParameter (
						i + 1, array_param.Attributes, array_param.Name);
				}
			}

			if (GetData != null)
				IsImplementing = GetData.IsImplementing;
			else if (SetData != null)
				IsImplementing = SetData.IsImplementing;

			//
			// Define the PropertyBuilder if one of the following conditions are met:
			// a) we're not implementing an interface indexer.
			// b) the indexer has a different IndexerName and this is no
			//    explicit interface implementation.
			//
			if (!IsExplicitImpl) {
				PropertyBuilder = parent.TypeBuilder.DefineProperty (
					IndexerName, prop_attr, MemberType, ParameterTypes);

				if (GetData != null)
					PropertyBuilder.SetGetMethod (GetBuilder);

				if (SetData != null)
					PropertyBuilder.SetSetMethod (SetBuilder);
				
				TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
							     ParameterTypes);
			}

			return true;
		}
Пример #25
0
			public override MethodBuilder Define (TypeContainer parent)
			{
				parameters.Resolve (this);
				
				base.Define (parent);

				Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, ModFlags);

				method_data = new MethodData (method, ModFlags, flags, this);

				if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
					return null;

				method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo);

				return method_data.MethodBuilder;
			}
Пример #26
0
		public override void Emit ()
		{
			if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
				Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder);
			if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
				Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder);

			if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
				return_attributes = new ReturnParameter (this, MethodBuilder, Location);
				Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
			} else if (ReturnType.HasDynamicElement) {
				return_attributes = new ReturnParameter (this, MethodBuilder, Location);
				Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
			}

			if (OptAttributes != null)
				OptAttributes.Emit ();

			if (declarative_security != null) {
				foreach (var de in declarative_security) {
#if STATIC
					MethodBuilder.__AddDeclarativeSecurity (de);
#else
					MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
#endif
				}
			}

			if (type_expr != null)
				ConstraintChecker.Check (this, member_type, type_expr.Location);

			base.Emit ();

			if (MethodData != null)
				MethodData.Emit (Parent);

			Block = null;
			MethodData = null;
		}
Пример #27
0
		public void ImplementMethod (MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one, out MethodSpec ambiguousCandidate, ref bool optional)
		{
			InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll, out ambiguousCandidate, ref optional);
		}
Пример #28
0
			public virtual MethodBuilder Define (DeclSpace parent)
			{
				// Fill in already resolved event type to speed things up and
				// avoid confusing duplicate errors
				((Parameter) parameters.FixedParameters[0]).Type = method.member_type;
				parameters.Types = new TypeSpec[] { method.member_type };

				method_data = new MethodData (method, method.ModFlags,
					method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);

				if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
					return null;

				MethodBuilder mb = method_data.MethodBuilder;

				Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags);
				Spec.IsAccessor = true;

				return mb;
			}
Пример #29
0
		public override bool Define ()
		{
			if (!base.Define ())
				return false;

			if (!CheckBase ())
				return false;

			MemberKind kind;
			if (this is Operator)
				kind = MemberKind.Operator;
			else if (this is Destructor)
				kind = MemberKind.Destructor;
			else
				kind = MemberKind.Method;

			string explicit_name;

			if (IsPartialDefinition) {
				caching_flags &= ~Flags.Excluded_Undetected;
				caching_flags |= Flags.Excluded;

				// Add to member cache only when a partial method implementation has not been found yet
				if ((caching_flags & Flags.PartialDefinitionExists) != 0)
					return true;

				if (IsExplicitImpl)
					return true;

				explicit_name = null;
			} else {
				MethodData = new MethodData (this, ModFlags, flags, this, base_method);

				if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
					return false;

				explicit_name = MethodData.MetadataName;
			}

			spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, parameters, ModFlags);
			if (MemberName.Arity > 0)
				spec.IsGeneric = true;

			Parent.MemberCache.AddMember (this, explicit_name, spec);

			return true;
		}
Пример #30
0
 /// <summary>
 ///   Whether the specified method is an interface method implementation
 /// </summary>
 public MethodSpec IsInterfaceMethod(MemberName name, TypeSpec ifaceType, MethodData method, out MethodSpec ambiguousCandidate, ref bool optional)
 {
     return(InterfaceMethod(name, ifaceType, method, Operation.Lookup, out ambiguousCandidate, ref optional));
 }