// // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Copyright (C) Lluis Sanchez Gual, 2004 // #if !FULL_AOT_RUNTIME using System; using System.Collections; using System.IO; using System.Reflection; using System.Reflection.Emit; namespace Mono.CodeGeneration { public class CodeProperty { PropertyInfo propertyInfo; CodeBuilder get_builder; CodeBuilder set_builder; string name; PropertyAttributes attributes; MethodAttributes methodAttributes; Type returnType; TypeBuilder typeBuilder; Type[] parameterTypes; ArrayList customAttributes = new ArrayList (); CodeClass cls; internal static CodeProperty DefineProperty (CodeClass cls, string name, PropertyAttributes attributes, MethodAttributes methodAttributes, Type returnType, Type[] parameterTypes) { return new CodeProperty (cls, name, attributes, methodAttributes, returnType, parameterTypes); } internal CodeProperty (CodeClass cls, string name, PropertyAttributes attributes, MethodAttributes methodAttributes, Type returnType, Type[] parameterTypes) { this.cls = cls; this.typeBuilder = cls.TypeBuilder; this.name = name; this.attributes = attributes; this.methodAttributes = methodAttributes; this.returnType = returnType; this.parameterTypes = parameterTypes; PropertyBuilder pb = typeBuilder.DefineProperty (name, attributes, returnType, parameterTypes); pb.SetGetMethod (typeBuilder.DefineMethod ("get_" + name, methodAttributes, CallingConventions.Standard, returnType, Type.EmptyTypes)); pb.SetSetMethod (typeBuilder.DefineMethod ("set_" + name, methodAttributes, CallingConventions.Standard, typeof (void), new Type [] {returnType})); get_builder = new CodeBuilder (cls); set_builder = new CodeBuilder (cls); propertyInfo = pb; } public TypeBuilder DeclaringType { get { return typeBuilder; } } public PropertyBuilder PropertyBuilder { get { return propertyInfo as PropertyBuilder; } } public string Name { get { return name; } } public PropertyAttributes Attributes { get { return attributes; } } public Type ReturnType { get { return returnType; } } public Type[] ParameterTypes { get { return parameterTypes; } } public CodeBuilder CodeBuilderGet { get { return get_builder; } } public CodeBuilder CodeBuilderSet { get { return set_builder; } } public bool IsStatic { get { return (methodAttributes & MethodAttributes.Static) != 0; } } public bool IsPublic { get { return (methodAttributes & MethodAttributes.Public) != 0; } } public CodeCustomAttribute CreateCustomAttribute (Type attributeType) { return CreateCustomAttribute (attributeType, Type.EmptyTypes, new object [0]); } public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, object [] ctorArgs) { return CreateCustomAttribute (attributeType, ctorArgTypes, ctorArgs, new string [0], new object [0]); } public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, object [] ctorArgs, string [] namedArgFieldNames, object [] namedArgValues) { CodeCustomAttribute cca = CodeCustomAttribute.Create ( attributeType, ctorArgTypes, ctorArgs, namedArgFieldNames, namedArgValues); SetCustomAttribute (cca); return cca; } public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, CodeLiteral [] ctorArgs, FieldInfo [] fields, CodeLiteral [] fieldValues) { CodeCustomAttribute cca = CodeCustomAttribute.Create ( attributeType, ctorArgTypes, ctorArgs, fields, fieldValues); SetCustomAttribute (cca); return cca; } void SetCustomAttribute (CodeCustomAttribute cca) { PropertyBuilder.SetCustomAttribute (cca.Builder); customAttributes.Add (cca); } public string PrintCode () { StringWriter sw = new StringWriter (); CodeWriter cw = new CodeWriter (sw); PrintCode (cw); return sw.ToString (); } public void PrintCode (CodeWriter cp) { cp.BeginLine (); foreach (CodeCustomAttribute a in customAttributes) a.PrintCode (cp); cp.BeginLine (); if (IsStatic) cp.Write ("static "); if (IsPublic) cp.Write ("public "); if (returnType != null) cp.Write (returnType + " "); cp.Write (name); if (parameterTypes.Length > 0) { cp.Write (name + " ["); for (int n=0; n 0) cp.Write (", "); cp.Write (parameterTypes[n] + " arg" + n); } cp.Write ("]"); } cp.Write (" {"); cp.EndLine (); cp.Indent (); cp.WriteLineInd ("get {"); get_builder.PrintCode (cp); cp.WriteLineUnind ("}"); cp.WriteLine ("set {"); set_builder.PrintCode (cp); cp.WriteLine ("}"); cp.WriteLineUnind ("}"); } public CodeArgumentReference GetArg (int n) { if (n < 0 || n >= parameterTypes.Length) throw new InvalidOperationException ("Invalid argument number"); int narg = IsStatic ? n : n + 1; return new CodeArgumentReference (parameterTypes[n], narg, "arg" + n); } public CodeArgumentReference GetThis () { if (IsStatic) throw new InvalidOperationException ("'this' not available in static methods"); return new CodeArgumentReference (DeclaringType, 0, "this"); } public void Generate () { ILGenerator gen; Label returnLabel; MethodBuilder mb; // getter mb = (MethodBuilder) propertyInfo.GetGetMethod (); if (mb != null) { gen = mb.GetILGenerator(); returnLabel = gen.DefineLabel (); get_builder.ReturnLabel = returnLabel; get_builder.Generate (gen); gen.MarkLabel (returnLabel); gen.Emit (OpCodes.Ret); } // setter mb = (MethodBuilder) propertyInfo.GetSetMethod (); if (mb != null) { gen = mb.GetILGenerator(); returnLabel = gen.DefineLabel (); set_builder.ReturnLabel = returnLabel; set_builder.Generate (gen); gen.MarkLabel (returnLabel); gen.Emit (OpCodes.Ret); } } public void UpdatePropertyInfo (Type type) { propertyInfo = type.GetProperty (propertyInfo.Name, parameterTypes); } } } #endif