📄 parameter.cs
字号:
//// parameter.cs: Parameter definition.//// Author: Miguel de Icaza (miguel@gnu.org)//// Licensed under the terms of the GNU GPL//// (C) 2001 Ximian, Inc (http://www.ximian.com)//////using System;using System.Reflection;using System.Reflection.Emit;using System.Collections;using System.Text;namespace Mono.CSharp { /// <summary> /// Abstract Base class for parameters of a method. /// </summary> public abstract class ParameterBase : Attributable { protected ParameterBuilder builder; public readonly Location Location; public ParameterBase (Attributes attrs, Location loc) : base (attrs) { Location = loc; } public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { if (a.Type == TypeManager.marshal_as_attr_type) { UnmanagedMarshal marshal = a.GetMarshal (this); if (marshal != null) { builder.SetMarshal (marshal); } return; } if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) { a.Error_InvalidSecurityParent (); return; } builder.SetCustomAttribute (cb); } public override bool IsClsCompliaceRequired(DeclSpace ds) { return false; } } /// <summary> /// Class for applying custom attributes on the return type /// </summary> public class ReturnParameter : ParameterBase { public ReturnParameter (MethodBuilder mb, Location location): base (null, location) { try { builder = mb.DefineParameter (0, ParameterAttributes.None, ""); } catch (ArgumentOutOfRangeException) { Report.Warning (-24, location, "The Microsoft .NET Runtime 1.x does not permit setting custom attributes on the return type"); } } public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb) { if (a.Type == TypeManager.cls_compliant_attribute_type) { Report.Warning (3023, 1, a.Location, "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead"); } // This occurs after Warning -28 if (builder == null) return; base.ApplyAttributeBuilder (a, cb); } public override AttributeTargets AttributeTargets { get { return AttributeTargets.ReturnValue; } } /// <summary> /// Is never called /// </summary> public override string[] ValidAttributeTargets { get { return null; } } } /// <summary> /// Class for applying custom attributes on the implicit parameter type /// of the 'set' method in properties, and the 'add' and 'remove' methods in events. /// </summary> public class ImplicitParameter : ParameterBase { public ImplicitParameter (MethodBuilder mb, Location loc): base (null, loc) { builder = mb.DefineParameter (1, ParameterAttributes.None, ""); } public override AttributeTargets AttributeTargets { get { return AttributeTargets.Parameter; } } /// <summary> /// Is never called /// </summary> public override string[] ValidAttributeTargets { get { return null; } } } /// <summary> /// Represents a single method parameter /// </summary> public class Parameter : ParameterBase { [Flags] public enum Modifier : byte { NONE = 0, REF = 1, OUT = 2, PARAMS = 4, // This is a flag which says that it's either REF or OUT. ISBYREF = 8, ARGLIST = 16 } static string[] attribute_targets = new string [] { "param" }; public Expression TypeName; public readonly Modifier ModFlags; public readonly string Name; Type parameter_type; EmitContext ec; // because ApplyAtrribute doesn't have ec public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc) : base (attrs, loc) { Name = name; ModFlags = mod; TypeName = type; } public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { if (a.Type == TypeManager.in_attribute_type && Attributes == ParameterAttributes.Out) { Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute"); return; } if (a.Type == TypeManager.param_array_type) { Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead"); return; } if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) != 0 && !OptAttributes.Contains (TypeManager.in_attribute_type, ec)) { Report.Error (662, a.Location, "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither"); return; } if (a.Type == TypeManager.cls_compliant_attribute_type) { Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead"); } base.ApplyAttributeBuilder (a, cb); } // <summary> // Resolve is used in method definitions // </summary> public bool Resolve (EmitContext ec) { this.ec = ec; TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false); if (texpr == null) return false; parameter_type = texpr.ResolveType (ec); if (parameter_type.IsAbstract && parameter_type.IsSealed) { Report.Error (721, Location, "`{0}': static types cannot be used as parameters", GetSignatureForError ()); return false; } if (parameter_type == TypeManager.void_type){ 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, Location, "Method or delegate parameter cannot be of type `{0}'", GetSignatureForError ()); return false; } } return parameter_type != null; } public Type ExternalType () { if ((ModFlags & Parameter.Modifier.ISBYREF) != 0) return TypeManager.GetReferenceType (parameter_type); return parameter_type; } public Type ParameterType { get { return parameter_type; } } public ParameterAttributes Attributes { get { int flags = ((int) ModFlags) & ~((int) Parameter.Modifier.ISBYREF); switch ((Modifier) flags) { case Modifier.NONE: return ParameterAttributes.None; case Modifier.REF: return ParameterAttributes.None; case Modifier.OUT: return ParameterAttributes.Out; case Modifier.PARAMS: return 0; } return ParameterAttributes.None; } } public override AttributeTargets AttributeTargets { get { return AttributeTargets.Parameter; } } /// <summary> /// Returns the signature for this parameter evaluating it on the /// @tc context /// </summary> public string GetSignature (EmitContext ec) { if (parameter_type == null){ if (!Resolve (ec)) return null; } return ExternalType ().FullName; } public string GetSignatureForError () { string type_name; if (parameter_type != null) type_name = TypeManager.CSharpName (parameter_type); else if (TypeName.Type != null) type_name = TypeManager.CSharpName (TypeName.Type); else type_name = TypeName.ToString (); 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"; case Modifier.PARAMS: return "params"; case Modifier.REF: return "ref"; case Modifier.ARGLIST: return "__arglist"; default: return ""; } } public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index) { ParameterAttributes par_attr = Attributes; if (mb == null) builder = cb.DefineParameter (index, par_attr, Name); else builder = mb.DefineParameter (index, par_attr, Name); if (OptAttributes != null) { OptAttributes.Emit (ec, this); } } public override string[] ValidAttributeTargets { get { return attribute_targets; } } } /// <summary> /// Represents the methods parameters
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -