annotate Source/TypeBuilder/Builders/DefaultTypeBuilder.cs @ 3:1ef98bd70424

!bug 100 +3h Исправление проблемы BLToolkit + mono 3.4
author cin
date Fri, 22 Aug 2014 17:34:46 +0400
parents f990fcb411a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2 using System.Collections;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4 using System.Reflection.Emit;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5 using System.Collections.Generic;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7 namespace BLToolkit.TypeBuilder.Builders
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9 using Properties;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10 using Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11 using Reflection.Emit;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13 public class DefaultTypeBuilder : AbstractTypeBuilderBase
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 #region Interface Overrides
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17 public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19 return IsRelative(typeBuilder) == false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22 public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24 if (context == null) throw new ArgumentNullException("context");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26 if (context.IsAbstractProperty && context.IsBeforeOrBuildStep)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28 return context.CurrentProperty.GetIndexParameters().Length <= 1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31 return context.BuildElement == BuildElement.Type && context.IsAfterStep;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36 #region Get/Set Implementation
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38 protected override void BuildAbstractGetter()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40 var field = GetField();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41 var index = Context.CurrentProperty.GetIndexParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43 switch (index.Length)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45 case 0:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46 Context.MethodBuilder.Emitter
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48 .ldfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49 .stloc (Context.ReturnValue)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53 case 1:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 Context.MethodBuilder.Emitter
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56 .ldfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58 .boxIfValueType (index[0].ParameterType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59 .callvirt (typeof(Dictionary<object,object>), "get_Item", typeof(object))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60 .castType (Context.CurrentProperty.PropertyType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61 .stloc (Context.ReturnValue)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67 protected override void BuildAbstractSetter()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 var field = GetField();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70 var index = Context.CurrentProperty.GetIndexParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72 switch (index.Length)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74 case 0:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75 Context.MethodBuilder.Emitter
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80 //Context.MethodBuilder.Emitter.AddMaxStackSize(6);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83 case 1:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84 Context.MethodBuilder.Emitter
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86 .ldfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88 .boxIfValueType (index[0].ParameterType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89 .ldarg_2
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90 .boxIfValueType (Context.CurrentProperty.PropertyType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91 .callvirt (typeof(Dictionary<object,object>), "set_Item", typeof(object), typeof(object))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99 #region Call Base Method
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101 protected override void BuildVirtualGetter()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 CallBaseMethod();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 protected override void BuildVirtualSetter()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108 CallBaseMethod();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 protected override void BuildVirtualMethod()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113 CallBaseMethod();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116 private void CallBaseMethod()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118 var emit = Context.MethodBuilder.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119 var method = Context.MethodBuilder.OverriddenMethod;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 var ps = method.GetParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 emit.ldarg_0.end();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124 for (var i = 0; i < ps.Length; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125 emit.ldarg(i + 1);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 emit.call(method);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129 if (Context.ReturnValue != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 emit.stloc(Context.ReturnValue);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135 #region Properties
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137 private static TypeHelper _initContextType;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 protected static TypeHelper InitContextType
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
139 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
140 get { return _initContextType ?? (_initContextType = new TypeHelper(typeof(InitContext))); }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
141 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
142
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
143 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
144
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
145 #region Field Initialization
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
146
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
147 #region Overrides
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
148
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
149 protected override void BeforeBuildAbstractGetter()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
150 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
151 CallLazyInstanceInsurer(GetField());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
152 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
153
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
154 protected override void BeforeBuildAbstractSetter()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
155 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
156 var field = GetField();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
157
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
158 if (field.FieldType != Context.CurrentProperty.PropertyType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
159 CallLazyInstanceInsurer(field);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
160 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
161
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
162 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
163
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
164 #region Common
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
165
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
166 protected FieldBuilder GetField()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
167 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
168 var propertyInfo = Context.CurrentProperty;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
169 var fieldName = GetFieldName();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
170 var fieldType = GetFieldType();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
171 var field = Context.GetField(fieldName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
172
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
173 if (field == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
174 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
175 field = Context.CreatePrivateField(propertyInfo, fieldName, fieldType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
176
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
177 if (TypeAccessor.IsInstanceBuildable(fieldType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
178 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
179 var noInstance = propertyInfo.GetCustomAttributes(typeof(NoInstanceAttribute), true).Length > 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
180
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
181 if (IsObjectHolder && noInstance)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
182 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
183 BuildHolderInstance(Context.TypeBuilder.DefaultConstructor.Emitter);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
184 BuildHolderInstance(Context.TypeBuilder.InitConstructor.Emitter);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
185 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
186 else if (!noInstance)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
187 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
188 if (fieldType.IsClass && IsLazyInstance(fieldType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
189 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
190 BuildLazyInstanceEnsurer();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
191 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
192 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
193 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
194 BuildDefaultInstance();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
195 BuildInitContextInstance();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
196 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
197 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
198 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
199 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
200
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
201 return field;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
202 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
203
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
204 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
205
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
206 #region Build
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
207
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
208 private void BuildHolderInstance(EmitHelper emit)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
209 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
210 var fieldName = GetFieldName();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
211 var field = Context.GetField(fieldName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
212 var fieldType = new TypeHelper(field.FieldType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
213 var objectType = new TypeHelper(GetObjectType());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
214
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
215 var ci = fieldType.GetPublicDefaultConstructor();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
216
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
217 if (ci != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
218 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
219 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
220 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
221 .newobj (ci)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
222 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
223 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
224 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
225 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
226 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
227 if (!CheckObjectHolderCtor(fieldType, objectType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
228 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
229
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
230 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
231 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
232 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
233 .newobj (fieldType, objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
234 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
235 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
236 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
237 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
238
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
239 private void CreateDefaultInstance(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
240 FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
241 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
242 if (!CheckObjectHolderCtor(fieldType, objectType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
243 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
244
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
245 if (objectType.Type == typeof(string))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
246 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
247 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
248 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
249 .LoadInitValue (objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
250 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
251 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
252 else if (objectType.IsArray)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
253 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
254 var initializer = GetArrayInitializer(objectType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
255
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
256 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
257 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
258 .ldsfld (initializer)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
259 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
260 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
261 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
262 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
263 var ci = objectType.GetPublicDefaultConstructor();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
264
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
265 if (ci == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
266 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
267 if (objectType.Type.IsValueType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
268 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
269
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
270 var message = string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
271 Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
272 Context.CurrentProperty.Name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
273 Context.Type.FullName,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
274 objectType.FullName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
275
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
276 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
277 .ldstr (message)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
278 .newobj (typeof(TypeBuilderException), typeof(string))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
279 .@throw
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
280 .end()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
281 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
282
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
283 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
284 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
285
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
286 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
287 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
288 .newobj (ci)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
289 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
290 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
291
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
292 if (IsObjectHolder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
293 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
294 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
295 .newobj (fieldType, objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
296 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
297 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
298
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
299 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
300 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
301 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
302 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
303
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
304 private void CreateParametrizedInstance(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
305 FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
306 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
307 if (!CheckObjectHolderCtor(fieldType, objectType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
308 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
309
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
310 Stack<ConstructorInfo> genericNestedConstructors;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
311 if (parameters.Length == 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
312 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
313 var o = parameters[0];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
314
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
315 if (o == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
316 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
317 if (objectType.IsValueType == false)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
318 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
319 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
320 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
321 .end()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
322 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
323
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
324 if (IsObjectHolder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
325 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
326 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
327 .newobj (fieldType, objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
328 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
329 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
330 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
331 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
332 if (objectType.Type.IsGenericType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
333 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
334 Type nullableType = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
335 genericNestedConstructors = GetGenericNestedConstructors(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
336 objectType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
337 typeHelper =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
338 typeHelper.IsValueType == false ||
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
339 (typeHelper.Type.IsGenericType && typeHelper.Type.GetGenericTypeDefinition() == typeof (Nullable<>)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
340 typeHelper => { nullableType = typeHelper.Type; },
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
341 () => nullableType != null);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
342
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
343 if (nullableType == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
344 throw new Exception("Cannot find nullable type in generic types chain");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
345
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
346 if (nullableType.IsValueType == false)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
347 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
348 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
349 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
350 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
351 .end()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
352 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
353 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
354 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
355 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
356 var nullable = emit.DeclareLocal(nullableType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
357
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
358 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
359 .ldloca(nullable)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
360 .initobj(nullableType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
361 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
362 .ldloc(nullable)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
363 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
364
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
365 if (genericNestedConstructors != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
366 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
367 while (genericNestedConstructors.Count != 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
368 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
369 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
370 .newobj(genericNestedConstructors.Pop())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
371 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
372 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
373 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
374 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
375 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
376 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
377
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
378 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
379 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
380 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
381
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
382 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
383 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
384
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
385 if (objectType.Type == o.GetType())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
386 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
387 if (objectType.Type == typeof(string))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
388 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
389 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
390 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
391 .ldstr ((string)o)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
392 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
393 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
394
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
395 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
396 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
397
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
398 if (objectType.IsValueType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
399 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
400 emit.ldarg_0.end();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
401
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
402 if (emit.LoadWellKnownValue(o) == false)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
403 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
404 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
405 .ldsfld (GetParameterField())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
406 .ldc_i4_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
407 .ldelem_ref
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
408 .end()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
409 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
410 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
411
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
412 emit.stfld(field);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
413
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
414 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
415 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
416 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
417 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
418
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
419 var types = new Type[parameters.Length];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
420
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
421 for (var i = 0; i < parameters.Length; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
422 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
423 if (parameters[i] != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
424 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
425 var t = parameters[i].GetType();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
426
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
427 types[i] = (t.IsEnum) ? Enum.GetUnderlyingType(t) : t;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
428 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
429 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
430 types[i] = typeof(object);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
431 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
432
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
433 // Do some heuristics for Nullable<DateTime> and EditableValue<Decimal>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
434 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
435 ConstructorInfo objectCtor = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
436 genericNestedConstructors = GetGenericNestedConstructors(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
437 objectType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
438 typeHelper => true,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
439 typeHelper => { objectCtor = typeHelper.GetPublicConstructor(types); },
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
440 () => objectCtor != null);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
441
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
442 if (objectCtor == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
443 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
444 if (objectType.IsValueType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
445 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
446
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
447 throw new TypeBuilderException(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
448 string.Format(types.Length == 0?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
449 Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
450 Resources.TypeBuilder_PropertyTypeHasNoPublicCtor,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
451 Context.CurrentProperty.Name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
452 Context.Type.FullName,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
453 objectType.FullName));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
454 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
455
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
456 var pi = objectCtor.GetParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
457
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
458 emit.ldarg_0.end();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
459
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
460 for (var i = 0; i < parameters.Length; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
461 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
462 var o = parameters[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
463 var oType = o.GetType();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
464
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
465 if (emit.LoadWellKnownValue(o))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
466 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
467 if (oType.IsValueType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
468 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
469 if (!pi[i].ParameterType.IsValueType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
470 emit.box(oType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
471 else if (Type.GetTypeCode(oType) != Type.GetTypeCode(pi[i].ParameterType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
472 emit.conv(pi[i].ParameterType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
473 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
474 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
475 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
476 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
477 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
478 .ldsfld (GetParameterField())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
479 .ldc_i4 (i)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
480 .ldelem_ref
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
481 .CastFromObject (types[i])
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
482 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
483
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
484 if (oType.IsValueType && !pi[i].ParameterType.IsValueType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
485 emit.box(oType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
486 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
487 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
488
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
489 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
490 .newobj (objectCtor)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
491 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
492
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
493 if (genericNestedConstructors != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
494 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
495 while (genericNestedConstructors.Count != 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
496 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
497 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
498 .newobj(genericNestedConstructors.Pop())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
499 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
500 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
501 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
502
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
503 if (IsObjectHolder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
504 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
505 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
506 .newobj (fieldType, objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
507 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
508 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
509
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
510 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
511 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
512 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
513 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
514
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
515 private Stack<ConstructorInfo> GetGenericNestedConstructors(TypeHelper objectType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
516 Predicate<TypeHelper> isActionable,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
517 Action<TypeHelper> action,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
518 Func<bool> isBreakCondition)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
519 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
520 Stack<ConstructorInfo> genericNestedConstructors = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
521
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
522 if (isActionable(objectType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
523 action(objectType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
524
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
525 while (objectType.Type.IsGenericType && !isBreakCondition())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
526 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
527 var typeArgs = objectType.Type.GetGenericArguments();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
528
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
529 if (typeArgs.Length == 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
530 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
531 var genericCtor = objectType.GetPublicConstructor(typeArgs[0]);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
532
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
533 if (genericCtor != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
534 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
535 if (genericNestedConstructors == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
536 genericNestedConstructors = new Stack<ConstructorInfo>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
537
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
538 genericNestedConstructors.Push(genericCtor);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
539 objectType = typeArgs[0];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
540
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
541 if (isActionable(objectType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
542 action(objectType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
543 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
544 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
545 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
546 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
547 throw new TypeBuilderException(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
548 string.Format(Resources.TypeBuilder_GenericShouldBeSingleTyped,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
549 Context.CurrentProperty.Name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
550 Context.Type.FullName,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
551 objectType.FullName));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
552 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
553 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
554
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
555 return genericNestedConstructors;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
556 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
557
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
558 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
559
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
560 #region Build InitContext Instance
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
561
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
562 private void BuildInitContextInstance()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
563 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
564 var fieldName = GetFieldName();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
565 var field = Context.GetField(fieldName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
566 var fieldType = new TypeHelper(field.FieldType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
567 var objectType = new TypeHelper(GetObjectType());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
568
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
569 var emit = Context.TypeBuilder.InitConstructor.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
570
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
571 var parameters = TypeHelper.GetPropertyParameters(Context.CurrentProperty);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
572 var ci = objectType.GetPublicConstructor(typeof(InitContext));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
573
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
574 if (ci != null && ci.GetParameters()[0].ParameterType != typeof(InitContext))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
575 ci = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
576
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
577 if (ci != null || objectType.IsAbstract)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
578 CreateAbstractInitContextInstance(field, fieldType, objectType, emit, parameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
579 else if (parameters == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
580 CreateDefaultInstance(field, fieldType, objectType, emit);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
581 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
582 CreateParametrizedInstance(field, fieldType, objectType, emit, parameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
583 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
584
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
585 private void CreateAbstractInitContextInstance(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
586 FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
587 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
588 if (!CheckObjectHolderCtor(fieldType, objectType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
589 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
590
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
591 var memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
592 var parentField = Context.GetItem<LocalBuilder>("$BLToolkit.InitContext.Parent");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
593
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
594 if (parentField == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
595 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
596 Context.Items.Add("$BLToolkit.InitContext.Parent", parentField = emit.DeclareLocal(typeof(object)));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
597
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
598 var label = emit.DefineLabel();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
599
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
600 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
601 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
602 .brtrue_s (label)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
603
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
604 .newobj (InitContextType.GetPublicDefaultConstructor())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
605 .starg (1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
606
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
607 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
608 .ldc_i4_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
609 .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
610
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
611 .MarkLabel (label)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
612
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
613 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
614 .callvirt (InitContextType.GetProperty("Parent").GetGetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
615 .stloc (parentField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
616 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
617 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
618
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
619 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
620 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
621 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
622 .callvirt (InitContextType.GetProperty("Parent").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
623 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
624
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
625 var isDirty = Context.GetItem<bool?>("$BLToolkit.InitContext.DirtyParameters");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
626
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
627 if (parameters != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
628 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
629 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
630 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
631 .ldsfld (GetParameterField())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
632 .callvirt (memberParams)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
633 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
634 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
635 else if (isDirty != null && (bool)isDirty)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
636 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
637 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
638 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
639 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
640 .callvirt (memberParams)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
641 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
642 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
643
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
644 if (Context.Items.ContainsKey("$BLToolkit.InitContext.DirtyParameters"))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
645 Context.Items["$BLToolkit.InitContext.DirtyParameters"] = (bool?)(parameters != null);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
646 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
647 Context.Items.Add("$BLToolkit.InitContext.DirtyParameters", (bool?)(parameters != null));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
648
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
649 if (objectType.IsAbstract)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
650 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
651 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
652 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
653 .ldsfld (GetTypeAccessorField())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
654 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
655 .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
656 .isinst (objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
657 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
658 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
659 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
660 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
661 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
662 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
663 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
664 .newobj (objectType.GetPublicConstructor(typeof(InitContext)))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
665 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
666 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
667
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
668 if (IsObjectHolder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
669 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
670 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
671 .newobj (fieldType, objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
672 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
673 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
674
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
675 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
676 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
677 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
678 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
679
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
680 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
681
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
682 #region Build Default Instance
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
683
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
684 private void BuildDefaultInstance()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
685 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
686 var fieldName = GetFieldName();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
687 var field = Context.GetField(fieldName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
688 var fieldType = new TypeHelper(field.FieldType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
689 var objectType = new TypeHelper(GetObjectType());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
690
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
691 var emit = Context.TypeBuilder.DefaultConstructor.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
692 var ps = TypeHelper.GetPropertyParameters(Context.CurrentProperty);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
693 var ci = objectType.GetPublicConstructor(typeof(InitContext));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
694
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
695 if (ci != null && ci.GetParameters()[0].ParameterType != typeof(InitContext))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
696 ci = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
697
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
698 if (ci != null || objectType.IsAbstract)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
699 CreateInitContextDefaultInstance(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
700 "$BLToolkit.DefaultInitContext.", field, fieldType, objectType, emit, ps);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
701 else if (ps == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
702 CreateDefaultInstance(field, fieldType, objectType, emit);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
703 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
704 CreateParametrizedInstance(field, fieldType, objectType, emit, ps);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
705 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
706
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
707 private bool CheckObjectHolderCtor(TypeHelper fieldType, TypeHelper objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
708 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
709 if (IsObjectHolder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
710 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
711 var holderCi = fieldType.GetPublicConstructor(objectType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
712
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
713 if (holderCi == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
714 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
715 var message = string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
716 Resources.TypeBuilder_PropertyTypeHasNoCtorWithParamType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
717 Context.CurrentProperty.Name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
718 Context.Type.FullName,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
719 fieldType.FullName,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
720 objectType.FullName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
721
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
722 Context.TypeBuilder.DefaultConstructor.Emitter
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
723 .ldstr (message)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
724 .newobj (typeof(TypeBuilderException), typeof(string))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
725 .@throw
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
726 .end()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
727 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
728
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
729 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
730 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
731 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
732
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
733 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
734 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
735
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
736 private void CreateInitContextDefaultInstance(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
737 string initContextName,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
738 FieldBuilder field,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
739 TypeHelper fieldType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
740 TypeHelper objectType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
741 EmitHelper emit,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
742 object[] parameters)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
743 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
744 if (!CheckObjectHolderCtor(fieldType, objectType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
745 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
746
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
747 var initField = GetInitContextBuilder(initContextName, emit);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
748 var memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
749
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
750 if (parameters != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
751 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
752 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
753 .ldloc (initField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
754 .ldsfld (GetParameterField())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
755 .callvirt (memberParams)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
756 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
757 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
758 else if ((bool)Context.Items["$BLToolkit.Default.DirtyParameters"])
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
759 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
760 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
761 .ldloc (initField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
762 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
763 .callvirt (memberParams)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
764 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
765 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
766
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
767 Context.Items["$BLToolkit.Default.DirtyParameters"] = parameters != null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
768
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
769 if (objectType.IsAbstract)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
770 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
771 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
772 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
773 .ldsfld (GetTypeAccessorField())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
774 .ldloc (initField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
775 .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
776 .isinst (objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
777 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
778 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
779 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
780 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
781 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
782 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
783 .ldloc (initField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
784 .newobj (objectType.GetPublicConstructor(typeof(InitContext)))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
785 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
786 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
787
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
788 if (IsObjectHolder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
789 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
790 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
791 .newobj (fieldType, objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
792 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
793 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
794
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
795 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
796 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
797 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
798 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
799
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
800 private LocalBuilder GetInitContextBuilder(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
801 string initContextName, EmitHelper emit)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
802 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
803 var initField = Context.GetItem<LocalBuilder>(initContextName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
804
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
805 if (initField == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
806 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
807 Context.Items.Add(initContextName, initField = emit.DeclareLocal(InitContextType));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
808
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
809 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
810 .newobj (InitContextType.GetPublicDefaultConstructor())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
811
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
812 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
813 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
814 .callvirt (InitContextType.GetProperty("Parent").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
815
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
816 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
817 .ldc_i4_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
818 .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
819
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
820 .stloc (initField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
821 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
822
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
823 Context.Items.Add("$BLToolkit.Default.DirtyParameters", false);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
824 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
825
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
826 return initField;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
827 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
828
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
829 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
830
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
831 #region Build Lazy Instance
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
832
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
833 private bool IsLazyInstance(Type type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
834 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
835 var attrs = Context.CurrentProperty.GetCustomAttributes(typeof(LazyInstanceAttribute), true);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
836
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
837 if (attrs.Length > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
838 return ((LazyInstanceAttribute)attrs[0]).IsLazy;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
839
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
840 attrs = Context.Type.GetAttributes(typeof(LazyInstancesAttribute));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
841
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
842 foreach (LazyInstancesAttribute a in attrs)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
843 if (a.Type == typeof(object) || type == a.Type || type.IsSubclassOf(a.Type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
844 return a.IsLazy;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
845
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
846 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
847 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
848
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
849 private void BuildLazyInstanceEnsurer()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
850 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
851 var fieldName = GetFieldName();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
852 var field = Context.GetField(fieldName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
853 var fieldType = new TypeHelper(field.FieldType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
854 var objectType = new TypeHelper(GetObjectType());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
855 var ensurer = Context.TypeBuilder.DefineMethod(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
856 string.Format("$EnsureInstance{0}", fieldName),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
857 MethodAttributes.Private | MethodAttributes.HideBySig);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
858
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
859 var emit = ensurer.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
860 var end = emit.DefineLabel();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
861
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
862 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
863 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
864 .ldfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
865 .brtrue_s (end)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
866 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
867
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
868 var parameters = TypeHelper.GetPropertyParameters(Context.CurrentProperty);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
869 var ci = objectType.GetPublicConstructor(typeof(InitContext));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
870
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
871 if (ci != null || objectType.IsAbstract)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
872 CreateInitContextLazyInstance(field, fieldType, objectType, emit, parameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
873 else if (parameters == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
874 CreateDefaultInstance(field, fieldType, objectType, emit);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
875 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
876 CreateParametrizedInstance(field, fieldType, objectType, emit, parameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
877
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
878 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
879 .MarkLabel(end)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
880 .ret()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
881 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
882
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
883 Context.Items.Add("$BLToolkit.FieldInstanceEnsurer." + fieldName, ensurer);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
884 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
885
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
886 private void CreateInitContextLazyInstance(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
887 FieldBuilder field,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
888 TypeHelper fieldType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
889 TypeHelper objectType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
890 EmitHelper emit,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
891 object[] parameters)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
892 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
893 if (!CheckObjectHolderCtor(fieldType, objectType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
894 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
895
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
896 var initField = emit.DeclareLocal(InitContextType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
897
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
898 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
899 .newobj (InitContextType.GetPublicDefaultConstructor())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
900
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
901 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
902 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
903 .callvirt (InitContextType.GetProperty("Parent").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
904
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
905 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
906 .ldc_i4_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
907 .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
908
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
909 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
910 .ldc_i4_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
911 .callvirt (InitContextType.GetProperty("IsLazyInstance").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
912
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
913 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
914
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
915 if (parameters != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
916 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
917 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
918 .dup
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
919 .ldsfld (GetParameterField())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
920 .callvirt (InitContextType.GetProperty("MemberParameters").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
921 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
922 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
923
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
924 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
925 .stloc (initField);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
926
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
927 if (objectType.IsAbstract)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
928 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
929 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
930 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
931 .ldsfld (GetTypeAccessorField())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
932 .ldloc (initField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
933 .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
934 .isinst (objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
935 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
936 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
937 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
938 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
939 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
940 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
941 .ldloc (initField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
942 .newobj (objectType.GetPublicConstructor(typeof(InitContext)))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
943 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
944 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
945
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
946 if (IsObjectHolder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
947 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
948 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
949 .newobj (fieldType, objectType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
950 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
951 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
952
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
953 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
954 .stfld (field)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
955 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
956 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
957
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
958 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
959
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
960 #region Finalize Type
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
961
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
962 protected override void AfterBuildType()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
963 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
964 var isDirty = Context.GetItem<bool?>("$BLToolkit.InitContext.DirtyParameters");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
965
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
966 if (isDirty != null && isDirty.Value)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
967 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
968 Context.TypeBuilder.InitConstructor.Emitter
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
969 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
970 .ldnull
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
971 .callvirt (InitContextType.GetProperty("MemberParameters").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
972 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
973 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
974
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
975 var localBuilder = Context.GetItem<LocalBuilder>("$BLToolkit.InitContext.Parent");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
976
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
977 if (localBuilder != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
978 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
979 Context.TypeBuilder.InitConstructor.Emitter
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
980 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
981 .ldloc (localBuilder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
982 .callvirt (InitContextType.GetProperty("Parent").GetSetMethod())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
983 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
984 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
985
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
986 FinalizeDefaultConstructors();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
987 FinalizeInitContextConstructors();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
988 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
989
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
990 private void FinalizeDefaultConstructors()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
991 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
992 var ci = Context.Type.GetDefaultConstructor();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
993
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
994 if (ci == null || Context.TypeBuilder.IsDefaultConstructorDefined)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
995 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
996 var emit = Context.TypeBuilder.DefaultConstructor.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
997
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
998 if (ci != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
999 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1000 emit.ldarg_0.call(ci);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1001 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1002 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1003 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1004 ci = Context.Type.GetConstructor(typeof(InitContext));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1005
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1006 if (ci != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1007 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1008 var initField = GetInitContextBuilder("$BLToolkit.DefaultInitContext.", emit);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1009
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1010 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1011 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1012 .ldloc (initField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1013 .call (ci);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1014 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1015 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1016 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1017 if (Context.Type.GetConstructors().Length > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1018 throw new TypeBuilderException(string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1019 Resources.TypeBuilder_NoDefaultCtor,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1020 Context.Type.FullName));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1021 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1022 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1023 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1024 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1025
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1026 private void FinalizeInitContextConstructors()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1027 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1028 var ci = Context.Type.GetConstructor(typeof(InitContext));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1029
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1030 if (ci != null || Context.TypeBuilder.IsInitConstructorDefined)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1031 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1032 var emit = Context.TypeBuilder.InitConstructor.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1033
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1034 if (ci != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1035 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1036 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1037 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1038 .ldarg_1
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1039 .call (ci);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1040 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1041 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1042 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1043 ci = Context.Type.GetDefaultConstructor();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1044
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1045 if (ci != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1046 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1047 emit.ldarg_0.call(ci);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1048 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1049 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1050 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1051 if (Context.Type.GetConstructors().Length > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1052 throw new TypeBuilderException(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1053 string.Format(Resources.TypeBuilder_NoDefaultCtor,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1054 Context.Type.FullName));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1055 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1056 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1057 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1058 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1059
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1060 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1061
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1062 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1063 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1064 }