172
173
this.MethodModifier = MethodModifier;
176
class ReturnTypeStepper
178
Stack<IReturnType> stack = new Stack<IReturnType> ();
180
public IReturnType Cur {
182
return stack.Peek ();
186
public bool HasNext {
188
return stack.Count > 0;
192
public ReturnTypeStepper (IReturnType returnType)
194
stack .Push (returnType);
199
if (stack.Count == 0)
201
IReturnType cur = stack.Pop ();
202
foreach (var generic in cur.GenericArguments.Reverse ()) {
203
stack.Push (generic);
210
if (stack.Count == 0)
175
219
public static IMethod CreateInstantiatedGenericMethod (IMethod method, IList<IReturnType> genericArguments, IList<IReturnType> methodArguments)
177
// System.Console.WriteLine("----");
178
// Console.WriteLine ("instantiate: " + method);
221
//System.Console.WriteLine("----");
222
//Console.WriteLine ("instantiate: " + method);
179
223
GenericMethodInstanceResolver resolver = new GenericMethodInstanceResolver ();
180
224
if (genericArguments != null) {
181
225
for (int i = 0; i < method.TypeParameters.Count && i < genericArguments.Count; i++)
182
resolver.Add (new DomReturnType (method.TypeParameters[i].Name), genericArguments[i]);
226
resolver.Add (method.DeclaringType != null ? method.DeclaringType.SourceProjectDom : null, new DomReturnType (method.TypeParameters [i].Name), genericArguments [i]);
184
228
IMethod result = (IMethod)method.AcceptVisitor (resolver, method);
185
229
resolver = new GenericMethodInstanceResolver ();
186
if (methodArguments != null) {
187
// The stack should contain <TEMPLATE> / RealType pairs
188
Stack<KeyValuePair<IReturnType, IReturnType>> returnTypeStack = new Stack<KeyValuePair<IReturnType, IReturnType>> ();
189
for (int i = 0; i < method.Parameters.Count && i < methodArguments.Count; i++) {
190
// Console.WriteLine ("parameter:" + method.Parameters[i]);
191
returnTypeStack.Push (new KeyValuePair<IReturnType, IReturnType> (method.Parameters[i].ReturnType, methodArguments[i]));
192
while (returnTypeStack.Count > 0) {
193
KeyValuePair<IReturnType, IReturnType> curReturnType = returnTypeStack.Pop ();
194
// Console.WriteLine ("key:" + curReturnType.Key + "/ val:" + curReturnType.Value);
196
for (int j = 0; j < method.TypeParameters.Count; j++) {
197
if (method.TypeParameters[j].Name == curReturnType.Key.FullName) {
203
resolver.Add (curReturnType.Key, curReturnType.Value);
206
//Console.WriteLine ("key:" + curReturnType.Key);
207
//Console.WriteLine ("value:" + curReturnType.Value);
208
for (int k = 0; k < System.Math.Min (curReturnType.Key.GenericArguments.Count, curReturnType.Value.GenericArguments.Count); k++) {
209
//Console.WriteLine ("add " + curReturnType.Key.GenericArguments[k] + " " + curReturnType.Value.GenericArguments[k]);
210
returnTypeStack.Push (new KeyValuePair<IReturnType, IReturnType> (curReturnType.Key.GenericArguments[k],
211
curReturnType.Value.GenericArguments[k]));
230
var containerSet = new HashSet<ITypeParameter> (method.TypeParameters);
232
for (int i = 0; i < method.Parameters.Count && i < methodArguments.Count; i++) {
233
ReturnTypeStepper original = new ReturnTypeStepper (method.Parameters [i].ReturnType);
234
ReturnTypeStepper argument = new ReturnTypeStepper (methodArguments [i]);
235
while (original.HasNext && argument.HasNext) {
236
if (containerSet.Any (p => p.Name == original.Cur.DecoratedFullName)) {
237
resolver.Add (method.DeclaringType != null ? method.DeclaringType.SourceProjectDom : null, original.Cur, argument.Cur);
216
// System.Console.WriteLine("before:" + result);
247
// if (methodArguments != null) {
248
// // The stack should contain <TEMPLATE> / RealType pairs
249
// Stack<KeyValuePair<IReturnType, IReturnType>> returnTypeStack = new Stack<KeyValuePair<IReturnType, IReturnType>> ();
250
// for (int i = 0; i < method.Parameters.Count && i < methodArguments.Count; i++) {
251
// returnTypeStack.Push (new KeyValuePair<IReturnType, IReturnType> (method.Parameters[i].ReturnType, methodArguments[i]));
252
// while (returnTypeStack.Count > 0) {
253
// KeyValuePair<IReturnType, IReturnType> curReturnType = returnTypeStack.Pop ();
254
// //Console.WriteLine ("key:" + curReturnType.Key + "\n val:" + curReturnType.Value);
255
// bool found = false;
256
// for (int j = 0; j < method.TypeParameters.Count; j++) {
257
// if (method.TypeParameters[j].Name == curReturnType.Key.FullName) {
263
// resolver.Add (method.DeclaringType != null ? method.DeclaringType.SourceProjectDom : null, curReturnType.Key, curReturnType.Value);
266
// //Console.WriteLine ("key:" + curReturnType.Key);
267
// //Console.WriteLine ("value:" + curReturnType.Value);
268
// for (int k = 0; k < System.Math.Min (curReturnType.Key.GenericArguments.Count, curReturnType.Value.GenericArguments.Count); k++) {
269
// //Console.WriteLine ("add " + curReturnType.Key.GenericArguments[k] + " " + curReturnType.Value.GenericArguments[k]);
270
// returnTypeStack.Push (new KeyValuePair<IReturnType, IReturnType> (curReturnType.Key.GenericArguments[k],
271
// curReturnType.Value.GenericArguments[k]));
276
// System.Console.WriteLine("before:" + result);
217
277
result = (IMethod)result.AcceptVisitor (resolver, result);
218
278
((DomMethod)result).DeclaringType = method.DeclaringType;
219
279
((DomMethod)result).MethodModifier = method.MethodModifier;
221
// System.Console.WriteLine("after:" + result);
222
// Console.WriteLine (result.Parameters[0]);
281
// System.Console.WriteLine("after:" + result);
282
// Console.WriteLine (result.Parameters[0]);
226
internal class GenericMethodInstanceResolver: CopyDomVisitor<IMethod>
286
public class GenericMethodInstanceResolver: CopyDomVisitor<IMethod>
228
288
public Dictionary<string, IReturnType> typeTable = new Dictionary<string,IReturnType> ();
230
public void Add (IReturnType parameterType, IReturnType type)
290
public void Add (ProjectDom dom, IReturnType parameterType, IReturnType type)
232
//Console.WriteLine ("Add:" + parameterType +"->" + type);
292
// Console.WriteLine ("Add:" + parameterType +"\n\t->" + type);
233
293
if (type == null || string.IsNullOrEmpty (type.FullName))
235
295
string name = parameterType.Name;
236
if (!typeTable.ContainsKey (name)) {
237
DomReturnType newType = new DomReturnType (type.FullName);
238
newType.ArrayDimensions = Math.Max (0, type.ArrayDimensions - parameterType.ArrayDimensions);
239
newType.PointerNestingLevel = Math.Max (0, type.PointerNestingLevel - parameterType.PointerNestingLevel);
240
newType.Type = type.Type; // May be anonymous type
241
for (int i = 0; i < newType.ArrayDimensions; i++)
242
newType.SetDimension (i, parameterType.GetDimension (i));
243
foreach (var generic in type.GenericArguments)
244
newType.AddTypeParameter (generic);
245
typeTable[name] = newType;
296
bool contains = typeTable.ContainsKey (name);
298
// when the type is already in the table use the type that is more general in the inheritance tree.
299
if (contains && dom != null) {
300
var t1 = dom.GetType (typeTable[name]);
301
var t2 = dom.GetType (type);
302
if (t1 != null && !dom.GetInheritanceTree (t1).Any (t => t.DecoratedFullName == t2.DecoratedFullName))
306
DomReturnType newType = new DomReturnType (type.FullName);
307
newType.ArrayDimensions = Math.Max (0, type.ArrayDimensions - parameterType.ArrayDimensions);
308
newType.PointerNestingLevel = Math.Max (0, type.PointerNestingLevel - parameterType.PointerNestingLevel);
309
newType.Type = type.Type; // May be anonymous type
310
for (int i = 0; i < newType.ArrayDimensions; i++)
311
newType.SetDimension (i, parameterType.GetDimension (i));
312
foreach (var generic in type.GenericArguments)
313
newType.AddTypeParameter (generic);
314
typeTable[name] = newType;
249
317
public override INode Visit (IMethod source, IMethod data)