📄 parameter.cs
字号:
/// </summary> public class Parameters { public Parameter [] FixedParameters; public readonly Parameter ArrayParameter; public readonly bool HasArglist; string signature; Type [] types; static Parameters empty_parameters; public Parameters (Parameter [] fixed_parameters, Parameter array_parameter) { FixedParameters = fixed_parameters; ArrayParameter = array_parameter; } public Parameters (Parameter [] fixed_parameters, bool has_arglist) { FixedParameters = fixed_parameters; HasArglist = has_arglist; } /// <summary> /// This is used to reuse a set of empty parameters, because they /// are common /// </summary> public static Parameters EmptyReadOnlyParameters { get { if (empty_parameters == null) empty_parameters = new Parameters (null, null); return empty_parameters; } } public bool Empty { get { return (FixedParameters == null) && (ArrayParameter == null); } } public void ComputeSignature (EmitContext ec) { signature = ""; if (FixedParameters != null){ for (int i = 0; i < FixedParameters.Length; i++){ Parameter par = FixedParameters [i]; signature += par.GetSignature (ec); } } // // Note: as per the spec, the `params' arguments (ArrayParameter) // are not used in the signature computation for a method // } void Error_DuplicateParameterName (string name, Location loc) { Report.Error ( 100, loc, "The parameter name `" + name + "' is a duplicate"); } public bool VerifyArgs () { int count; int i, j; if (FixedParameters == null) 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 (base_name != FixedParameters [j].Name) continue; Error_DuplicateParameterName (base_name, FixedParameters [i].Location); return false; } if (base_name == array_par_name){ Error_DuplicateParameterName (base_name, FixedParameters [i].Location); return false; } } return true; } /// <summary> /// Returns the signature of the Parameters evaluated in /// the @ec EmitContext /// </summary> public string GetSignature (EmitContext ec) { if (signature == null){ VerifyArgs (); ComputeSignature (ec); } return signature; } /// <summary> /// Returns the paramenter information based on the name /// </summary> public Parameter GetParameterByName (string name, out int idx) { idx = 0; int i = 0; if (FixedParameters != null){ foreach (Parameter par in FixedParameters){ if (par.Name == name){ idx = i; return par; } i++; } } if (ArrayParameter != null){ if (name == ArrayParameter.Name){ idx = i; return ArrayParameter; } } return null; } public Parameter GetParameterByName (string name) { int idx; return GetParameterByName (name, out idx); } bool ComputeParameterTypes (EmitContext ec) { 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 failed = false; if (FixedParameters != null){ foreach (Parameter p in FixedParameters){ Type t = null; if (p.Resolve (ec)) t = p.ExternalType (); else failed = true; types [i] = t; i++; } } if (extra > 0){ if (ArrayParameter.Resolve (ec)) types [i] = ArrayParameter.ExternalType (); else failed = true; } if (failed){ types = null; return false; } return true; } /// <summary> /// Returns the argument types as an array /// </summary> static Type [] no_types = new Type [0]; public Type [] GetParameterInfo (EmitContext ec) { if (types != null) return types; if (FixedParameters == null && ArrayParameter == null) return no_types; if (ComputeParameterTypes (ec) == false){ types = null; return null; } return types; } /// <summary> /// Returns the type of a given parameter, and stores in the `is_out' /// boolean whether this is an out or ref parameter. /// /// Note that the returned type will not contain any dereference in this /// case (ie, you get "int" for a ref int instead of "int&" /// </summary> public Type GetParameterInfo (EmitContext ec, int idx, out Parameter.Modifier mod) { mod = Parameter.Modifier.NONE; if (!VerifyArgs ()){ FixedParameters = null; return null; } if (FixedParameters == null && ArrayParameter == null) return null; if (types == null) if (ComputeParameterTypes (ec) == false) return null; // // If this is a request for the variable lenght arg. // 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]; mod = p.ModFlags; if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0) mod |= Parameter.Modifier.ISBYREF; return p.ParameterType; } public CallingConventions GetCallingConvention () { if (HasArglist) return CallingConventions.VarArgs; else return CallingConventions.Standard; } // // 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) { // // Define each type attribute (in/out/ref) and // the argument names. // int i = 0; MethodBuilder mb = builder as MethodBuilder; ConstructorBuilder cb = builder as ConstructorBuilder; if (FixedParameters != null) { for (i = 0; i < FixedParameters.Length; i++) { FixedParameters [i].DefineParameter (ec, mb, cb, i + 1); } } if (ArrayParameter != null){ ParameterBuilder pb; Parameter array_param = ArrayParameter; if (mb == null) pb = cb.DefineParameter ( i + 1, array_param.Attributes, array_param.Name); else pb = mb.DefineParameter ( i + 1, array_param.Attributes, array_param.Name); CustomAttributeBuilder a = new CustomAttributeBuilder ( TypeManager.cons_param_array_attribute, new object [0]); pb.SetCustomAttribute (a); } } public string GetSignatureForError () { StringBuilder sb = new StringBuilder ("("); if (FixedParameters != null) { for (int i = 0; i < FixedParameters.Length; ++i) { sb.Append (FixedParameters[i].GetSignatureForError ()); if (i < FixedParameters.Length - 1) sb.Append (", "); } } if (ArrayParameter != null) { if (sb.Length > 0) sb.Append (", "); sb.Append (ArrayParameter.GetSignatureForError ()); } if (HasArglist) { if (sb.Length > 0) sb.Append (", "); sb.Append ("__arglist"); } sb.Append (')'); return sb.ToString (); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -