- 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, /* was "value" */ this.Name);
-
- 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;
- }
- }
-
- public class Operator : MemberCore {
-
- const int AllowedModifiers =
- Modifiers.PUBLIC |
- Modifiers.UNSAFE |
- Modifiers.EXTERN |
- Modifiers.STATIC;
-
- const int RequiredModifiers =
- Modifiers.PUBLIC |
- Modifiers.STATIC;
-
- public enum OpType : byte {
-
- // Unary operators
- LogicalNot,
- OnesComplement,
- Increment,
- Decrement,
- True,
- False,
-
- // Unary and Binary operators
- Addition,
- Subtraction,
-
- UnaryPlus,
- UnaryNegation,
-
- // Binary operators
- Multiply,
- Division,
- Modulus,
- BitwiseAnd,
- BitwiseOr,
- ExclusiveOr,
- LeftShift,
- RightShift,
- Equality,
- Inequality,
- GreaterThan,
- LessThan,
- GreaterThanOrEqual,
- LessThanOrEqual,
-
- // Implicit and Explicit
- Implicit,
- Explicit
- };
-
- public readonly OpType OperatorType;
- public readonly Expression ReturnType;
- public readonly Expression FirstArgType, SecondArgType;
- public readonly string FirstArgName, SecondArgName;
- public readonly Block Block;
- public Attributes OptAttributes;
- public MethodBuilder OperatorMethodBuilder;
-
- public string MethodName;
- public Method OperatorMethod;
-
- public Operator (OpType type, Expression ret_type, int flags,
- Expression arg1type, string arg1name,
- Expression arg2type, string arg2name,
- Block block, Attributes attrs, Location loc)
- : base ("", loc)
- {
- OperatorType = type;
- ReturnType = ret_type;
- ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC, loc);
- FirstArgType = arg1type;
- FirstArgName = arg1name;
- SecondArgType = arg2type;
- SecondArgName = arg2name;
- Block = block;
- OptAttributes = attrs;
- }
-
- string Prototype (TypeContainer parent)
- {
- return parent.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
- SecondArgType + ")";
- }
-
- public override bool Define (TypeContainer parent)
- {
- int length = 1;
- MethodName = "op_" + OperatorType;
-
- if (SecondArgType != null)
- length = 2;
-
- Parameter [] param_list = new Parameter [length];
-
- if ((ModFlags & RequiredModifiers) != RequiredModifiers){
- Report.Error (
- 558, Location,
- "User defined operators `" +
- Prototype (parent) +
- "' must be declared static and public");
- return false;
- }
-
- param_list[0] = new Parameter (FirstArgType, FirstArgName,
- Parameter.Modifier.NONE, null);
- if (SecondArgType != null)
- param_list[1] = new Parameter (SecondArgType, SecondArgName,
- Parameter.Modifier.NONE, null);
-
- OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
- new Parameters (param_list, null, Location),
- OptAttributes, Mono.MonoBASIC.Location.Null);
-
- OperatorMethod.IsOperator = true;
- OperatorMethod.Define (parent);
-
- if (OperatorMethod.MethodBuilder == null)
- return false;
-
- OperatorMethodBuilder = OperatorMethod.MethodBuilder;
-
- Type [] param_types = OperatorMethod.ParameterTypes;
- Type declaring_type = OperatorMethodBuilder.DeclaringType;
- Type return_type = OperatorMethod.GetReturnType ();
- Type first_arg_type = param_types [0];
-
- // Rules for conversion operators
-
- if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
- if (first_arg_type == return_type && first_arg_type == declaring_type){
- Report.Error (
- 555, Location,
- "User-defined conversion cannot take an object of the " +
- "enclosing type and convert to an object of the enclosing" +
- " type");
- return false;
- }
-
- if (first_arg_type != declaring_type && return_type != declaring_type){
- Report.Error (
- 556, Location,
- "User-defined conversion must convert to or from the " +
- "enclosing type");
- return false;
- }
-
- if (first_arg_type == TypeManager.object_type ||
- return_type == TypeManager.object_type){
- Report.Error (
- -8, Location,
- "User-defined conversion cannot convert to or from " +
- "object type");
- return false;
- }
-
- if (first_arg_type.IsInterface || return_type.IsInterface){
- Report.Error (
- 552, Location,
- "User-defined conversion cannot convert to or from an " +
- "interface type");
- return false;
- }
-
- if (first_arg_type.IsSubclassOf (return_type) ||
- return_type.IsSubclassOf (first_arg_type)){
- Report.Error (
- -10, Location,
- "User-defined conversion cannot convert between types " +
- "that derive from each other");
- return false;
- }
- } else if (SecondArgType == null) {
- // Checks for Unary operators
-
- if (first_arg_type != declaring_type){
- Report.Error (
- 562, Location,
- "The parameter of a unary operator must be the " +
- "containing type");
- return false;
- }
-
- if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
- if (return_type != declaring_type){
- Report.Error (
- 559, Location,
- "The parameter and return type for ++ and -- " +
- "must be the containing type");
- return false;
- }
-
- }
-
- if (OperatorType == OpType.True || OperatorType == OpType.False) {
- if (return_type != TypeManager.bool_type){
- Report.Error (
- 215, Location,
- "The return type of operator True or False " +
- "must be bool");
- return false;
- }
- }
-
- } else {
- // Checks for Binary operators
-
- if (first_arg_type != declaring_type &&
- param_types [1] != declaring_type){
- Report.Error (
- 563, Location,
- "One of the parameters of a binary operator must " +
- "be the containing type");
- return false;
- }
- }