Example #1
0
		//
		// Checks our base implementation if any
		//
		protected override bool CheckBase (TypeContainer parent)
		{
			// Check whether arguments were correct.
			if (!DoDefineParameters (parent))
				return false;

			if (IsExplicitImpl)
				return true;

			string report_name;
			MethodSignature ms, base_ms;
			if (this is Indexer) {
				string name, base_name;

				report_name = "this";
				name = TypeManager.IndexerPropertyName (parent.TypeBuilder);
				ms = new MethodSignature (name, null, ParameterTypes);
				base_name = TypeManager.IndexerPropertyName (parent.TypeBuilder.BaseType);
				base_ms = new MethodSignature (base_name, null, ParameterTypes);
			} else {
				report_name = Name;
				ms = base_ms = new MethodSignature (Name, null, ParameterTypes);
			}

			//
			// Verify if the parent has a type with the same name, and then
			// check whether we have to create a new slot for it or not.
			//
			Type ptype = parent.TypeBuilder.BaseType;

			// ptype is only null for System.Object while compiling corlib.
			if (ptype == null) {
				if ((ModFlags & Modifiers.NEW) != 0)
					WarningNotHiding (parent);

				return true;
			}

			MemberList props_this;

			props_this = TypeContainer.FindMembers (
				parent.TypeBuilder, MemberTypes.Property,
				BindingFlags.NonPublic | BindingFlags.Public |
				BindingFlags.Static | BindingFlags.Instance |
				BindingFlags.DeclaredOnly,
				MethodSignature.method_signature_filter, ms);

			if (props_this.Count > 0) {
				Report.Error (111, Location, "Class `" + parent.Name + "' " +
					      "already defines a member called `" + report_name + "' " +
					      "with the same parameter types");
				return false;
			}

			MemberList mi_props;

			mi_props = TypeContainer.FindMembers (
				ptype, MemberTypes.Property,
				BindingFlags.NonPublic | BindingFlags.Public |
				BindingFlags.Instance | BindingFlags.Static,
				MethodSignature.inheritable_method_signature_filter, base_ms);

			if (mi_props.Count > 0){
				PropertyInfo parent_property = (PropertyInfo) mi_props [0];
				string name = parent_property.DeclaringType.Name + "." +
					parent_property.Name;

				MethodInfo get, set, parent_method;
				get = parent_property.GetGetMethod (true);
				set = parent_property.GetSetMethod (true);

				if (get != null)
					parent_method = get;
				else if (set != null)
					parent_method = set;
				else
					throw new Exception ("Internal error!");

				if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
					return false;

				if ((ModFlags & Modifiers.NEW) == 0) {
					Type parent_type = TypeManager.TypeToCoreType (
						parent_property.PropertyType);

					if (parent_type != MemberType) {
						Report.Error (
							508, Location, parent.MakeName (Name) + ": cannot " +
							"change return type when overriding " +
							"inherited member " + name);
						return false;
					}
				}
			} else {
				if ((ModFlags & Modifiers.NEW) != 0)
					WarningNotHiding (parent);

				if ((ModFlags & Modifiers.OVERRIDE) != 0){
					if (this is Indexer)
						Report.Error (115, Location,
							      parent.MakeName (Name) +
							      " no suitable indexers found to override");
					else
						Report.Error (115, Location,
							      parent.MakeName (Name) +
							      " no suitable properties found to override");
					return false;
				}
			}
			return true;
		}
Example #2
0
		//
		// Checks our base implementation if any
		//
		protected override bool CheckBase (TypeContainer parent)
		{
			// Check whether arguments were correct.
			if (!DoDefineParameters (parent))
				return false;

			MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
			if (IsOperator) {
				flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
			} else {
				MemberList mi_this;

				mi_this = TypeContainer.FindMembers (
					parent.TypeBuilder, MemberTypes.Method,
					BindingFlags.NonPublic | BindingFlags.Public |
					BindingFlags.Static | BindingFlags.Instance |
					BindingFlags.DeclaredOnly,
					MethodSignature.method_signature_filter, ms);

				if (mi_this.Count > 0) {
					Report.Error (111, Location, "Class `" + parent.Name + "' " +
						      "already defines a member called `" + Name + "' " +
						      "with the same parameter types");
					return false;
				}
			} 

			//
			// Verify if the parent has a type with the same name, and then
			// check whether we have to create a new slot for it or not.
			//
			Type ptype = parent.TypeBuilder.BaseType;

			// ptype is only null for System.Object while compiling corlib.
			if (ptype != null){
				MemberList mi, mi_static, mi_instance;

				mi_instance = TypeContainer.FindMembers (
					ptype, MemberTypes.Method,
					BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
					MethodSignature.inheritable_method_signature_filter,
					ms);

				if (mi_instance.Count > 0){
					mi = mi_instance;
				} else {
					mi_static = TypeContainer.FindMembers (
						ptype, MemberTypes.Method,
						BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
						MethodSignature.inheritable_method_signature_filter, ms);

					if (mi_static.Count > 0)
						mi = mi_static;
					else
						mi = null;
				}

				if (mi != null && mi.Count > 0){
					parent_method = (MethodInfo) mi [0];
					string name = parent_method.DeclaringType.Name + "." +
						parent_method.Name;

					if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
						return false;

					if ((ModFlags & Modifiers.NEW) == 0) {
						Type parent_ret = TypeManager.TypeToCoreType (
							parent_method.ReturnType);

						if (parent_ret != MemberType) {
							Report.Error (
								508, Location, parent.MakeName (Name) + ": cannot " +
								"change return type when overriding " +
								"inherited member " + name);
							return false;
						}
					}
				} else {
					if ((ModFlags & Modifiers.NEW) != 0)
						WarningNotHiding (parent);

					if ((ModFlags & Modifiers.OVERRIDE) != 0){
						Report.Error (115, Location,
							      parent.MakeName (Name) +
							      " no suitable methods found to override");
					}
				}
			} else if ((ModFlags & Modifiers.NEW) != 0)
				WarningNotHiding (parent);

			return true;
		}
Example #3
0
		private static MemberInfo [] FindMethodBase (Type type,
			BindingFlags binding_flags, MethodSignature signature)
		{
			MemberList ml = TypeManager.FindMembers (
				type,
				MemberTypes.Constructor | MemberTypes.Method | MemberTypes.Property | MemberTypes.Custom,
				binding_flags,
				MethodSignature.method_signature_filter,
				signature);
			if (ml == null)
				return empty_member_infos;

			return FilterOverridenMembersOut ((MemberInfo []) ml);
		}
Example #4
0
		private static MemberInfo FindDocumentedMemberNoNest (
			MemberCore mc, Type type, string member_name,
			Type [] param_list, DeclSpace ds, out int warning_type, 
			string cref, bool warn419, string name_for_error, Report Report)
		{
			warning_type = 0;
			MemberInfo [] mis;

			if (param_list == null) {
				// search for fields/events etc.
				mis = TypeManager.MemberLookup (type, null,
					type, MemberTypes.All,
					BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
					member_name, null);
				mis = FilterOverridenMembersOut (mis);
				if (mis == null || mis.Length == 0)
					return null;
				if (warn419 && IsAmbiguous (mis))
					Report419 (mc, name_for_error, mis, Report);
				return mis [0];
			}

			MethodSignature msig = new MethodSignature (member_name, null, param_list);
			mis = FindMethodBase (type, 
				BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
				msig);

			if (warn419 && mis.Length > 0) {
				if (IsAmbiguous (mis))
					Report419 (mc, name_for_error, mis, Report);
				return mis [0];
			}

			// search for operators (whose parameters exactly
			// matches with the list) and possibly report CS1581.
			string oper = null;
			string return_type_name = null;
			if (member_name.StartsWith ("implicit operator ")) {
				Operator.GetMetadataName (Operator.OpType.Implicit);
				return_type_name = member_name.Substring (18).Trim (wsChars);
			}
			else if (member_name.StartsWith ("explicit operator ")) {
				oper = Operator.GetMetadataName (Operator.OpType.Explicit);
				return_type_name = member_name.Substring (18).Trim (wsChars);
			}
			else if (member_name.StartsWith ("operator ")) {
				oper = member_name.Substring (9).Trim (wsChars);
				switch (oper) {
				// either unary or binary
				case "+":
					oper = param_list.Length == 2 ?
						Operator.GetMetadataName (Operator.OpType.Addition) :
						Operator.GetMetadataName (Operator.OpType.UnaryPlus);
					break;
				case "-":
					oper = param_list.Length == 2 ?
						Operator.GetMetadataName (Operator.OpType.Subtraction) :
						Operator.GetMetadataName (Operator.OpType.UnaryNegation);
					break;
				default:
					oper = Operator.GetMetadataName (oper);
					if (oper != null)
						break;

					warning_type = 1584;
					Report.Warning (1020, 1, mc.Location, "Overloadable {0} operator is expected", param_list.Length == 2 ? "binary" : "unary");
					Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
						mc.GetSignatureForError (), cref);
					return null;
				}
			}
			// here we still don't consider return type (to
			// detect CS1581 or CS1002+CS1584).
			msig = new MethodSignature (oper, null, param_list);

			mis = FindMethodBase (type, 
				BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
				msig);
			if (mis.Length == 0)
				return null; // CS1574
			MemberInfo mi = mis [0];
			Type expected = mi is MethodInfo ?
				((MethodInfo) mi).ReturnType :
				mi is PropertyInfo ?
				((PropertyInfo) mi).PropertyType :
				null;
			if (return_type_name != null) {
				Type returnType = FindDocumentedType (mc, return_type_name, ds, cref, Report);
				if (returnType == null || returnType != expected) {
					warning_type = 1581;
					Report.Warning (1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref);
					return null;
				}
			}
			return mis [0];
		}
		/// <summary>
		///   This function tells whether one of our base classes implements
		///   the given method (which turns out, it is valid to have an interface
		///   implementation in a base
		/// </summary>
		bool BaseImplements (Type iface_type, MethodInfo mi, out MethodInfo base_method)
		{
			MethodSignature ms;
			
			AParametersCollection param = TypeManager.GetParameterData (mi);
			ms = new MethodSignature (mi.Name, TypeManager.TypeToCoreType (mi.ReturnType), param.Types);
			MemberList list = TypeContainer.FindMembers (
				container.TypeBuilder.BaseType, MemberTypes.Method | MemberTypes.Property,
				BindingFlags.Public | BindingFlags.Instance,
				MethodSignature.method_signature_filter, ms);

			if (list.Count == 0) {
				base_method = null;
				return false;
			}

			if (TypeManager.ImplementsInterface (container.TypeBuilder.BaseType, iface_type)) {
				base_method = null;
				return true;
			}

			base_method = (MethodInfo) list [0];

			if (base_method.DeclaringType.IsInterface)
				return false;

			if (!base_method.IsPublic)
				return false;

			if (!base_method.IsAbstract && !base_method.IsVirtual)
				// FIXME: We can avoid creating a proxy if base_method can be marked 'final virtual' instead.
				//        However, it's too late now, the MethodBuilder has already been created (see bug 377519)
				DefineProxy (iface_type, base_method, mi, param);

			return true;
		}