X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fparameter.cs;h=d344c3a8dcdc12a8177c0a90a0d77ee8a67ff681;hb=5f0dc4802f69745ced8f32b39bd770f7bd134b8f;hp=eff976d93414f3e61d60f54f935aa31588a9f606;hpb=75b15060b976b16ab7673c9a1e9737add1de34ec;p=mono.git diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs index eff976d9341..d344c3a8dcd 100755 --- a/mcs/mcs/parameter.cs +++ b/mcs/mcs/parameter.cs @@ -23,19 +23,21 @@ namespace Mono.CSharp { public class Parameter { [Flags] public enum Modifier : byte { - NONE = 0, - REF = 1, - OUT = 2, - PARAMS = 4, + NONE = 0, + REF = 1, + OUT = 2, + PARAMS = 4, + // This is a flag which says that it's either REF or OUT. + ISBYREF = 8 } - public readonly string TypeName; - public readonly string Name; + public readonly Expression TypeName; public readonly Modifier ModFlags; public Attributes OptAttributes; - public Type ParameterType; + public readonly string Name; + public Type parameter_type; - public Parameter (string type, string name, Modifier mod, Attributes attrs) + public Parameter (Expression type, string name, Modifier mod, Attributes attrs) { Name = name; ModFlags = mod; @@ -43,38 +45,44 @@ namespace Mono.CSharp { OptAttributes = attrs; } - public bool Resolve (DeclSpace ds) + // + // Resolve is used in method definitions + // + public bool Resolve (DeclSpace ds, Location l) { - ParameterType = ds.LookupType (TypeName, false); - return ParameterType != null; + parameter_type = ds.ResolveType (TypeName, false, l); + + if (parameter_type == TypeManager.void_type){ + Report.Error (1536, l, "`void' parameter is not permitted"); + return false; + } + + return parameter_type != null; } - public Type ExternalType () + public Type ExternalType (DeclSpace ds, Location l) { - if ((ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0){ - string n = ParameterType.FullName + "&"; - Type t; - - t = Type.GetType (n); + if ((ModFlags & Parameter.Modifier.ISBYREF) != 0){ + string n = parameter_type.FullName + "&"; - // - // It is a type defined by the source code we are compiling - // - if (t == null){ - ModuleBuilder mb = RootContext.ModuleBuilder; - - t = mb.GetType (n); - } + Type t = RootContext.LookupType (ds, n, false, l); return t; } + + return parameter_type; + } - return ParameterType; + public Type ParameterType { + get { + return parameter_type; + } } public ParameterAttributes Attributes { get { - switch (ModFlags){ + int flags = ((int) ModFlags) & ~((int) Parameter.Modifier.ISBYREF); + switch ((Modifier) flags) { case Modifier.NONE: return ParameterAttributes.None; case Modifier.REF: @@ -93,14 +101,14 @@ namespace Mono.CSharp { /// Returns the signature for this parameter evaluating it on the /// @tc context /// - public string GetSignature (DeclSpace ds) + public string GetSignature (DeclSpace ds, Location loc) { - if (ParameterType == null){ - if (!Resolve (ds)) + if (parameter_type == null){ + if (!Resolve (ds, loc)) return null; } - return ExternalType ().FullName; + return ExternalType (ds, loc).FullName; } } @@ -112,25 +120,28 @@ namespace Mono.CSharp { public readonly Parameter ArrayParameter; string signature; Type [] types; + Location loc; static Parameters empty_parameters; - public Parameters (Parameter [] fixed_parameters, Parameter array_parameter) + public Parameters (Parameter [] fixed_parameters, Parameter array_parameter, Location l) { FixedParameters = fixed_parameters; ArrayParameter = array_parameter; + loc = l; } /// /// This is used to reuse a set of empty parameters, because they /// are common /// - public static Parameters GetEmptyReadOnlyParameters () - { - if (empty_parameters == null) - empty_parameters = new Parameters (null, null); + public static Parameters EmptyReadOnlyParameters { + get { + if (empty_parameters == null) + empty_parameters = new Parameters (null, null, Location.Null); - return empty_parameters; + return empty_parameters; + } } public bool Empty { @@ -139,14 +150,14 @@ namespace Mono.CSharp { } } - public void ComputeSignature (TypeContainer tc) + public void ComputeSignature (DeclSpace ds) { signature = ""; if (FixedParameters != null){ for (int i = 0; i < FixedParameters.Length; i++){ Parameter par = FixedParameters [i]; - signature += par.GetSignature (tc); + signature += par.GetSignature (ds, loc); } } // @@ -155,7 +166,13 @@ namespace Mono.CSharp { // } - public bool VerifyArgs (TypeContainer tc) + static void Error_DuplicateParameterName (string name) + { + Report.Error ( + 100, "The parameter name `" + name + "' is a duplicate"); + } + + public bool VerifyArgs () { int count; int i, j; @@ -164,13 +181,19 @@ namespace Mono.CSharp { return true; count = FixedParameters.Length; + string array_par_name = ArrayParameter != null ? ArrayParameter.Name : null; for (i = 0; i < count; i++){ + string base_name = FixedParameters [i].Name; + for (j = i + 1; j < count; j++){ - if (FixedParameters [i].Name != FixedParameters [j].Name) + if (base_name != FixedParameters [j].Name) continue; - Report.Error ( - 100, "The parameter name `" + FixedParameters [i].Name + - "' is a duplicate"); + Error_DuplicateParameterName (base_name); + return false; + } + + if (base_name == array_par_name){ + Error_DuplicateParameterName (base_name); return false; } } @@ -181,11 +204,11 @@ namespace Mono.CSharp { /// Returns the signature of the Parameters evaluated in /// the @tc environment /// - public string GetSignature (TypeContainer tc) + public string GetSignature (DeclSpace ds) { if (signature == null){ - VerifyArgs (tc); - ComputeSignature (tc); + VerifyArgs (); + ComputeSignature (ds); } return signature; @@ -197,75 +220,149 @@ namespace Mono.CSharp { public Parameter GetParameterByName (string name, out int idx) { idx = 0; - - if (FixedParameters == null) - return null; - int i = 0; - foreach (Parameter par in FixedParameters){ - if (par.Name == name){ - idx = i; - return par; + + if (FixedParameters != null){ + foreach (Parameter par in FixedParameters){ + if (par.Name == name){ + idx = i; + return par; + } + i++; } - i++; } - if (ArrayParameter != null) + if (ArrayParameter != null){ if (name == ArrayParameter.Name){ idx = i; return ArrayParameter; } + } return null; } - bool ComputeParameterTypes (TypeContainer tc) + bool ComputeParameterTypes (DeclSpace ds) { int extra = (ArrayParameter != null) ? 1 : 0; int i = 0; - int pc = FixedParameters.Length + extra; - + int pc; + + if (FixedParameters == null) + pc = extra; + else + pc = extra + FixedParameters.Length; + types = new Type [pc]; - if (!VerifyArgs (tc)){ + if (!VerifyArgs ()){ FixedParameters = null; return false; } + + bool failed = false; + if (FixedParameters != null){ + foreach (Parameter p in FixedParameters){ + Type t = null; + + if (p.Resolve (ds, loc)) + t = p.ExternalType (ds, loc); + else + failed = true; + + types [i] = t; + i++; + } + } - foreach (Parameter p in FixedParameters){ - Type t = null; - - if (p.Resolve (tc)) - t = p.ExternalType (); - - types [i] = t; - i++; + if (extra > 0){ + if (ArrayParameter.Resolve (ds, loc)) + types [i] = ArrayParameter.ExternalType (ds, loc); + else + failed = true; } - if (extra > 0){ - if (ArrayParameter.Resolve (tc)) - types [i] = ArrayParameter.ExternalType (); + if (failed){ + types = null; + return false; } return true; } + + // + // This variant is used by Delegates, because they need to + // resolve/define names, instead of the plain LookupType + // + public bool ComputeAndDefineParameterTypes (DeclSpace ds) + { + int extra = (ArrayParameter != null) ? 1 : 0; + int i = 0; + int pc; + + if (FixedParameters == null) + pc = extra; + else + pc = extra + FixedParameters.Length; + + types = new Type [pc]; + + if (!VerifyArgs ()){ + FixedParameters = null; + return false; + } + + bool ok_flag = true; + + if (FixedParameters != null){ + foreach (Parameter p in FixedParameters){ + Type t = null; + + if (p.Resolve (ds, loc)) + t = p.ExternalType (ds, loc); + else + ok_flag = false; + + types [i] = t; + i++; + } + } + + if (extra > 0){ + if (ArrayParameter.Resolve (ds, loc)) + types [i] = ArrayParameter.ExternalType (ds, loc); + else + ok_flag = false; + } + + // + // invalidate the cached types + // + if (!ok_flag){ + types = null; + } + + return ok_flag; + } /// /// Returns the argument types as an array /// static Type [] no_types = new Type [0]; - public Type [] GetParameterInfo (TypeContainer tc) + public Type [] GetParameterInfo (DeclSpace ds) { if (types != null) return types; - if (FixedParameters == null) + if (FixedParameters == null && ArrayParameter == null) return no_types; - if (ComputeParameterTypes (tc) == false) + if (ComputeParameterTypes (ds) == false){ + types = null; return null; - + } + return types; } @@ -276,37 +373,37 @@ namespace Mono.CSharp { /// Note that the returned type will not contain any dereference in this /// case (ie, you get "int" for a ref int instead of "int&" /// - public Type GetParameterInfo (TypeContainer tc, int idx, out bool is_out) + public Type GetParameterInfo (DeclSpace ds, int idx, out Parameter.Modifier mod) { - is_out = false; + mod = Parameter.Modifier.NONE; - if (!VerifyArgs (tc)){ + if (!VerifyArgs ()){ FixedParameters = null; return null; } - if (FixedParameters == null) + if (FixedParameters == null && ArrayParameter == null) return null; if (types == null) - if (ComputeParameterTypes (tc) == false){ - is_out = false; + if (ComputeParameterTypes (ds) == false) return null; - } // // If this is a request for the variable lenght arg. // - if (idx == FixedParameters.Length){ - is_out = false; + int array_idx = (FixedParameters != null ? FixedParameters.Length : 0); + if (idx == array_idx) return types [idx]; - } // // Otherwise, it is a fixed parameter // Parameter p = FixedParameters [idx]; - is_out = ((p.ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0); + mod = p.ModFlags; + + if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0) + mod |= Parameter.Modifier.ISBYREF; return p.ParameterType; }