ICSharpCode.NRefactory.MonoCSharp.Operator.Define C# (CSharp) 메소드

Define() 공개 메소드

public Define ( ) : bool
리턴 bool
		public override bool Define ()
		{
			const Modifiers RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
			if ((ModFlags & RequiredModifiers) != RequiredModifiers){
				Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
			}

			if (!base.Define ())
				return false;

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

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

			// imlicit and explicit operator of same types are not allowed
			if (OperatorType == OpType.Explicit)
				Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
			else if (OperatorType == OpType.Implicit)
				Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);

			TypeSpec declaring_type = Parent.CurrentType;
			TypeSpec return_type = MemberType;
			TypeSpec first_arg_type = ParameterTypes [0];
			
			TypeSpec first_arg_type_unwrap = first_arg_type;
			if (first_arg_type.IsNullableType)
				first_arg_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (first_arg_type);
			
			TypeSpec return_type_unwrap = return_type;
			if (return_type.IsNullableType)
				return_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (return_type);

			//
			// Rules for conversion operators
			//
			if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
				if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type) {
					Report.Error (555, Location,
						"User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
					return false;
				}

				TypeSpec conv_type;
				if (declaring_type == return_type || declaring_type == return_type_unwrap) {
					conv_type = first_arg_type;
				} else if (declaring_type == first_arg_type || declaring_type == first_arg_type_unwrap) {
					conv_type = return_type;
				} else {
					Report.Error (556, Location,
						"User-defined conversion must convert to or from the enclosing type");
					return false;
				}

				if (conv_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
					Report.Error (1964, Location,
						"User-defined conversion `{0}' cannot convert to or from the dynamic type",
						GetSignatureForError ());

					return false;
				}

				if (conv_type.IsInterface) {
					Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
						GetSignatureForError ());
					return false;
				}

				if (conv_type.IsClass) {
					if (TypeSpec.IsBaseClass (declaring_type, conv_type, true)) {
						Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
							GetSignatureForError ());
						return false;
					}

					if (TypeSpec.IsBaseClass (conv_type, declaring_type, false)) {
						Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
							GetSignatureForError ());
						return false;
					}
				}
			} else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
				if (first_arg_type != declaring_type || parameters.Types[1].BuiltinType != BuiltinTypeSpec.Type.Int) {
					Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
					return false;
				}
			} else if (parameters.Count == 1) {
				// Checks for Unary operators

				if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
					if (return_type != declaring_type && !TypeSpec.IsBaseClass (return_type, declaring_type, false)) {
						Report.Error (448, Location,
							"The return type for ++ or -- operator must be the containing type or derived from the containing type");
						return false;
					}
					if (first_arg_type != declaring_type) {
						Report.Error (
							559, Location, "The parameter type for ++ or -- operator must be the containing type");
						return false;
					}
				}

				if (first_arg_type_unwrap != declaring_type) {
					Report.Error (562, Location,
						"The parameter type of a unary operator must be the containing type");
					return false;
				}

				if (OperatorType == OpType.True || OperatorType == OpType.False) {
					if (return_type.BuiltinType != BuiltinTypeSpec.Type.Bool) {
						Report.Error (
							215, Location,
							"The return type of operator True or False " +
							"must be bool");
						return false;
					}
				}

			} else if (first_arg_type_unwrap != declaring_type) {
				// Checks for Binary operators

				var second_arg_type = ParameterTypes[1];
				if (second_arg_type.IsNullableType)
					second_arg_type = Nullable.NullableInfo.GetUnderlyingType (second_arg_type);

				if (second_arg_type != declaring_type) {
					Report.Error (563, Location,
						"One of the parameters of a binary operator must be the containing type");
					return false;
				}
			}

			return true;
		}