2005-05-31 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / mcs / parameter.cs
index fb9e69b54b2af7accc04c731ca6d7a6b2269b789..cfe1f907bdd3e75f1df084e283ebc2349ad07afd 100644 (file)
@@ -22,10 +22,12 @@ namespace Mono.CSharp {
        public abstract class ParameterBase : Attributable {
 
                protected ParameterBuilder builder;
+               public readonly Location Location;
 
-               public ParameterBase (Attributes attrs)
+               public ParameterBase (Attributes attrs, Location loc)
                        : base (attrs)
                {
+                       Location = loc;
                }
 
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
@@ -57,7 +59,7 @@ namespace Mono.CSharp {
        /// </summary>
        public class ReturnParameter: ParameterBase {
                public ReturnParameter (MethodBuilder mb, Location location):
-                       base (null)
+                       base (null, location)
                {
                        try {
                                builder = mb.DefineParameter (0, ParameterAttributes.None, "");                 
@@ -101,8 +103,8 @@ namespace Mono.CSharp {
        /// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
        /// </summary>
        public class ImplicitParameter: ParameterBase {
-               public ImplicitParameter (MethodBuilder mb):
-                       base (null)
+               public ImplicitParameter (MethodBuilder mb, Location loc):
+                       base (null, loc)
                {
                        builder = mb.DefineParameter (1, ParameterAttributes.None, "");                 
                }
@@ -126,8 +128,6 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Represents a single method parameter
        /// </summary>
-
-       //TODO: Add location member to this or base class for better error location and all methods simplification.
        public class Parameter : ParameterBase {
                [Flags]
                public enum Modifier : byte {
@@ -149,8 +149,8 @@ namespace Mono.CSharp {
 
                EmitContext ec;  // because ApplyAtrribute doesn't have ec
                
-               public Parameter (Expression type, string name, Modifier mod, Attributes attrs)
-                       : base (attrs)
+               public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
+                       : base (attrs, loc)
                {
                        Name = name;
                        ModFlags = mod;
@@ -186,7 +186,7 @@ namespace Mono.CSharp {
                // <summary>
                //   Resolve is used in method definitions
                // </summary>
-               public bool Resolve (EmitContext ec, Location l)
+               public bool Resolve (EmitContext ec)
                {
                        this.ec = ec;
 
@@ -197,19 +197,19 @@ namespace Mono.CSharp {
                        parameter_type = texpr.ResolveType (ec);
                        
                        if (parameter_type.IsAbstract && parameter_type.IsSealed) {
-                               Report.Error (721, l, "'{0}': static types cannot be used as parameters", GetSignatureForError ());
+                               Report.Error (721, Location, "'{0}': static types cannot be used as parameters", GetSignatureForError ());
                                return false;
                        }
 
                        if (parameter_type == TypeManager.void_type){
-                               Report.Error (1536, l, "Invalid parameter type 'void'");
+                               Report.Error (1536, Location, "Invalid parameter type 'void'");
                                return false;
                        }
 
                        if ((ModFlags & Parameter.Modifier.ISBYREF) != 0){
                                if (parameter_type == TypeManager.typed_reference_type ||
                                    parameter_type == TypeManager.arg_iterator_type){
-                                       Report.Error (1601, l,
+                                       Report.Error (1601, Location,
                                                      "out or ref parameter can not be of type TypedReference or ArgIterator");
                                        return false;
                                }
@@ -260,10 +260,10 @@ namespace Mono.CSharp {
                ///   Returns the signature for this parameter evaluating it on the
                ///   @tc context
                /// </summary>
-               public string GetSignature (EmitContext ec, Location loc)
+               public string GetSignature (EmitContext ec)
                {
                        if (parameter_type == null){
-                               if (!Resolve (ec, loc))
+                               if (!Resolve (ec))
                                        return null;
                        }
 
@@ -280,18 +280,30 @@ namespace Mono.CSharp {
                        else
                                type_name = TypeName.ToString ();
 
-                       switch (ModFlags & unchecked (~Modifier.ISBYREF)) {
+                       string mod = GetModifierSignature (ModFlags);
+                       if (mod.Length > 0)
+                               return String.Concat (mod, " ", type_name);
+
+                       return type_name;
+               }
+
+               public static string GetModifierSignature (Modifier mod)
+               {
+                       switch (mod & unchecked (~Modifier.ISBYREF)) {
                                case Modifier.OUT:
-                                       return "out " + type_name;
+                                       return "out";
                                case Modifier.PARAMS:
-                                       return "params " + type_name;
+                                       return "params";
                                case Modifier.REF:
-                                       return "ref " + type_name;
+                                       return "ref";
+                               case Modifier.ARGLIST:
+                                       return "__arglist";
+                               default:
+                                       return "";
                        }
-                       return type_name;
                }
 
-               public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index, Location loc)
+               public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index)
                {
                        ParameterAttributes par_attr = Attributes;
                                        
@@ -321,22 +333,19 @@ namespace Mono.CSharp {
                public readonly bool HasArglist;
                string signature;
                Type [] types;
-               Location loc;
                
                static Parameters empty_parameters;
                
-               public Parameters (Parameter [] fixed_parameters, Parameter array_parameter, Location l)
+               public Parameters (Parameter [] fixed_parameters, Parameter array_parameter)
                {
                        FixedParameters = fixed_parameters;
                        ArrayParameter  = array_parameter;
-                       loc = l;
                }
 
-               public Parameters (Parameter [] fixed_parameters, bool has_arglist, Location l)
+               public Parameters (Parameter [] fixed_parameters, bool has_arglist)
                {
                        FixedParameters = fixed_parameters;
                        HasArglist = has_arglist;
-                       loc = l;
                }
 
                /// <summary>
@@ -346,7 +355,7 @@ namespace Mono.CSharp {
                public static Parameters EmptyReadOnlyParameters {
                        get {
                                if (empty_parameters == null)
-                                       empty_parameters = new Parameters (null, null, Location.Null);
+                                       empty_parameters = new Parameters (null, null);
                        
                                return empty_parameters;
                        }
@@ -358,10 +367,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public Location Location {
-                       get { return loc; }
-               }
-               
                public void ComputeSignature (EmitContext ec)
                {
                        signature = "";
@@ -369,7 +374,7 @@ namespace Mono.CSharp {
                                for (int i = 0; i < FixedParameters.Length; i++){
                                        Parameter par = FixedParameters [i];
                                        
-                                       signature += par.GetSignature (ec, loc);
+                                       signature += par.GetSignature (ec);
                                }
                        }
                        //
@@ -378,7 +383,7 @@ namespace Mono.CSharp {
                        //
                }
 
-               void Error_DuplicateParameterName (string name)
+               void Error_DuplicateParameterName (string name, Location loc)
                {
                        Report.Error (
                                100, loc, "The parameter name `" + name + "' is a duplicate");
@@ -400,12 +405,14 @@ namespace Mono.CSharp {
                                for (j = i + 1; j < count; j++){
                                        if (base_name != FixedParameters [j].Name)
                                                continue;
-                                       Error_DuplicateParameterName (base_name);
+                                       Error_DuplicateParameterName (base_name,
+                                               FixedParameters [i].Location);
                                        return false;
                                }
 
                                if (base_name == array_par_name){
-                                       Error_DuplicateParameterName (base_name);
+                                       Error_DuplicateParameterName (base_name,
+                                               FixedParameters [i].Location);
                                        return false;
                                }
                        }
@@ -484,7 +491,7 @@ namespace Mono.CSharp {
                                foreach (Parameter p in FixedParameters){
                                        Type t = null;
                                        
-                                       if (p.Resolve (ec, loc))
+                                       if (p.Resolve (ec))
                                                t = p.ExternalType ();
                                        else
                                                failed = true;
@@ -495,7 +502,7 @@ namespace Mono.CSharp {
                        }
                        
                        if (extra > 0){
-                               if (ArrayParameter.Resolve (ec, loc))
+                               if (ArrayParameter.Resolve (ec))
                                        types [i] = ArrayParameter.ExternalType ();
                                else 
                                        failed = true;
@@ -584,9 +591,8 @@ namespace Mono.CSharp {
                // The method's attributes are passed in because we need to extract
                // the "return:" attribute from there to apply on the return type
                //
-               public void LabelParameters (EmitContext ec,
-                       MethodBase builder,
-                       Location loc) {
+               public void LabelParameters (EmitContext ec, MethodBase builder)
+               {
                        //
                        // Define each type attribute (in/out/ref) and
                        // the argument names.
@@ -598,7 +604,7 @@ namespace Mono.CSharp {
 
                        if (FixedParameters != null) {
                                for (i = 0; i < FixedParameters.Length; i++) {
-                                       FixedParameters [i].DefineParameter (ec, mb, cb, i + 1, loc);
+                                       FixedParameters [i].DefineParameter (ec, mb, cb, i + 1);
                                }
                        }