1: /*
2: Copyright (c) 2009 <a href="http://www.gutgames.com">James Craig</a>
3:
4: Permission is hereby granted, free of charge, to any person obtaining a copy
5: of this software and associated documentation files (the "Software"), to deal
6: in the Software without restriction, including without limitation the rights
7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: copies of the Software, and to permit persons to whom the Software is
9: furnished to do so, subject to the following conditions:
10:
11: The above copyright notice and this permission notice shall be included in
12: all copies or substantial portions of the Software.
13:
14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: THE SOFTWARE.*/
21:
22: #region Usings
23: using System;
24: using System.Collections.Generic;
25: using System.Linq;
26: using System.Text;
27: using System.Reflection.Emit;
28: using System.Reflection;
29: using HaterAide.Interfaces;
30: #endregion
31:
32: namespace HaterAide.Reflection
33: { 34: /// <summary>
35: /// Used to override a class
36: /// </summary>
37: internal class Class
38: { 39: public Class(Type Class, ModuleBuilder Module)
40: { 41: Type BaseType = Class.BaseType;
42: Type GenericType = BaseType.GetGenericArguments()[0];
43: TypeBuilder TypeBuilder = Module.DefineType("HaterAide0ClassesM." + GenericType.Name + "Derived", TypeAttributes.Public, GenericType); 44: FieldBuilder ChangedField = CreateChangedFields(TypeBuilder);
45: CreateChangedClearMethod(TypeBuilder, ChangedField);
46: CreateConstructor(ChangedField, TypeBuilder, GenericType);
47: OverrideProperties(ChangedField, TypeBuilder, Class);
48:
49: _DerivedType = TypeBuilder.CreateType();
50: }
51:
52: private void CreateChangedClearMethod(TypeBuilder TypeBuilder, FieldBuilder ChangedField)
53: { 54: MethodBuilder Method = TypeBuilder.DefineMethod("ClearChanged0", MethodAttributes.Public, typeof(void), new Type[0]); 55: ILGenerator Generator = Method.GetILGenerator();
56: Generator.Emit(OpCodes.Ldarg_0);
57: Generator.Emit(OpCodes.Ldfld, ChangedField);
58: Generator.Emit(OpCodes.Callvirt, typeof(List<string>).GetMethod("Clear")); 59: Generator.Emit(OpCodes.Ret);
60: }
61:
62: private void OverrideProperties(FieldBuilder ChangedField, TypeBuilder TypeBuilder, Type ClassMapper)
63: { 64: IAttributeMap Item = (IAttributeMap)Activator.CreateInstance(ClassMapper);
65: foreach (Attribute Property in Item.Properties)
66: { 67: if (Property.AttributeType == AttributeType.ID || Property.AttributeType == AttributeType.Reference)
68: { 69: Properties.Add(new Property(Property, TypeBuilder, ChangedField));
70: }
71: }
72: }
73:
74: private FieldBuilder CreateChangedFields(TypeBuilder TypeBuilder)
75: { 76: FieldBuilder ValueField = TypeBuilder.DefineField("_ChangedList0", typeof(List<string>), FieldAttributes.Private); 77: PropertyBuilder Property = TypeBuilder.DefineProperty("ChangedList0", PropertyAttributes.None, typeof(List<string>), null); 78:
79: MethodAttributes GetSetAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
80:
81: MethodBuilder ValuePropertyGet = TypeBuilder.DefineMethod("get_ChangedList0", GetSetAttributes, typeof(List<string>), Type.EmptyTypes); 82: ILGenerator Generator = ValuePropertyGet.GetILGenerator();
83: Generator.Emit(OpCodes.Ldarg_0);
84: Generator.Emit(OpCodes.Ldfld, ValueField);
85: Generator.Emit(OpCodes.Ret);
86:
87: MethodBuilder ValuePropertySet = TypeBuilder.DefineMethod("set_ChangedList0", GetSetAttributes, null, new Type[] { typeof(List<string>) }); 88: Generator = ValuePropertySet.GetILGenerator();
89: Generator.Emit(OpCodes.Ldarg_0);
90: Generator.Emit(OpCodes.Ldarg_1);
91: Generator.Emit(OpCodes.Stfld, ValueField);
92: Generator.Emit(OpCodes.Ret);
93:
94: Property.SetGetMethod(ValuePropertyGet);
95: Property.SetSetMethod(ValuePropertySet);
96:
97: return ValueField;
98: }
99:
100: private void CreateConstructor(FieldBuilder ChangedField, TypeBuilder TypeBuilder,Type GenericType)
101: { 102: ConstructorBuilder Constructor = TypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]);
103: ILGenerator Generator = Constructor.GetILGenerator();
104: Generator.Emit(OpCodes.Ldarg_0);
105: Generator.Emit(OpCodes.Call, GenericType.GetConstructor(new Type[0]));
106: Generator.Emit(OpCodes.Ldarg_0);
107: Generator.Emit(OpCodes.Newobj, typeof(List<string>).GetConstructor(new Type[0]));
108: Generator.Emit(OpCodes.Stfld, ChangedField);
109: Generator.Emit(OpCodes.Ret);
110: }
111:
112: private List<Property> _Properties = new List<Property>();
113:
114: private Type _DerivedType = null;
115:
116: public Type DerivedType
117: { 118: get { return _DerivedType; } 119: }
120:
121: public List<Property> Properties
122: { 123: get { return _Properties; } 124: }
125: }
126: }