~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Core/MonoDevelop.Projects.Dom/DomMethod.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
using System.Collections.ObjectModel;
32
32
using System.Text;
33
33
using System.Xml;
 
34
using System.Linq;
34
35
using MonoDevelop.Projects.Dom.Parser;
35
36
using MonoDevelop.Core;
36
37
 
130
131
                                        result.Append ("M:");
131
132
                                        result.Append (FullName);
132
133
                                        if (TypeParameters.Count > 0) {
133
 
                                                result.Append ("~");
 
134
                                                result.Append ("`");
134
135
                                                result.Append (TypeParameters.Count);
135
136
                                        }
136
137
                                }
172
173
                        this.MethodModifier = MethodModifier;
173
174
                }
174
175
                
 
176
                class ReturnTypeStepper
 
177
                {
 
178
                        Stack<IReturnType> stack = new Stack<IReturnType> ();
 
179
                        
 
180
                        public IReturnType Cur {
 
181
                                get {
 
182
                                        return stack.Peek ();
 
183
                                }
 
184
                        }
 
185
                        
 
186
                        public bool HasNext {
 
187
                                get {
 
188
                                        return stack.Count > 0;
 
189
                                }
 
190
                        }
 
191
                        
 
192
                        public ReturnTypeStepper (IReturnType returnType)
 
193
                        {
 
194
                                stack .Push (returnType);
 
195
                        }
 
196
                        
 
197
                        public bool Step ()
 
198
                        {
 
199
                                if (stack.Count == 0)
 
200
                                        return false;
 
201
                                IReturnType cur = stack.Pop ();
 
202
                                foreach (var generic in cur.GenericArguments.Reverse ()) {
 
203
                                        stack.Push (generic);
 
204
                                }
 
205
                                return true;
 
206
                        }
 
207
                        
 
208
                        public bool Skip ()
 
209
                        {
 
210
                                if (stack.Count == 0)
 
211
                                        return false;
 
212
                                stack.Pop ();
 
213
                                return true;
 
214
                        }
 
215
                        
 
216
                        
 
217
                }
 
218
                
175
219
                public static IMethod CreateInstantiatedGenericMethod (IMethod method, IList<IReturnType> genericArguments, IList<IReturnType> methodArguments)
176
220
                {
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]);
183
227
                        }
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);
195
 
                                                bool found = false;
196
 
                                                for (int j = 0; j < method.TypeParameters.Count; j++) {
197
 
                                                        if (method.TypeParameters[j].Name == curReturnType.Key.FullName) {
198
 
                                                                found = true;
199
 
                                                                break;
200
 
                                                        }
201
 
                                                }
202
 
                                                if (found) {
203
 
                                                        resolver.Add (curReturnType.Key, curReturnType.Value);
204
 
                                                        continue;
205
 
                                                }
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]));
212
 
                                                }
 
230
                        var containerSet = new HashSet<ITypeParameter> (method.TypeParameters);
 
231
                        
 
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);
 
238
                                                original.Skip ();
 
239
                                                argument.Skip ();
 
240
                                        } else {
 
241
                                                original.Step ();
 
242
                                                argument.Step ();
213
243
                                        }
214
244
                                }
215
245
                        }
216
 
//                      System.Console.WriteLine("before:" + result);
 
246
                        
 
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) {
 
258
                        //                                                              found = true;
 
259
                        //                                                              break;
 
260
                        //                                                      }
 
261
                        //                                              }
 
262
                        //                                              if (found) {
 
263
                        //                                                      resolver.Add (method.DeclaringType != null ? method.DeclaringType.SourceProjectDom : null, curReturnType.Key, curReturnType.Value);
 
264
                        //                                                      continue;
 
265
                        //                                              }
 
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]));
 
272
                        //                                              }
 
273
                        //                                      }
 
274
                        //                              }
 
275
                        //                      }
 
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;
220
280
                        
221
 
//                      System.Console.WriteLine("after:" + result);
222
 
//                      Console.WriteLine (result.Parameters[0]);
 
281
                        //                      System.Console.WriteLine("after:" + result);
 
282
                        //                      Console.WriteLine (result.Parameters[0]);
223
283
                        return result;
224
284
                }
225
285
                
226
 
                internal class GenericMethodInstanceResolver: CopyDomVisitor<IMethod>
 
286
                public class GenericMethodInstanceResolver: CopyDomVisitor<IMethod>
227
287
                {
228
288
                        public Dictionary<string, IReturnType> typeTable = new Dictionary<string,IReturnType> ();
229
289
                        
230
 
                        public void Add (IReturnType parameterType, IReturnType type)
 
290
                        public void Add (ProjectDom dom, IReturnType parameterType, IReturnType type)
231
291
                        {
232
 
                                //Console.WriteLine ("Add:" + parameterType +"->" + type);
 
292
//                              Console.WriteLine ("Add:" + parameterType +"\n\t->" + type);
233
293
                                if (type == null || string.IsNullOrEmpty (type.FullName))
234
294
                                        return;
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);
 
297
                                
 
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))
 
303
                                                return;
246
304
                                }
 
305
                                
 
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;
247
315
                        }
248
316
                        
249
317
                        public override INode Visit (IMethod source, IMethod data)
274
342
                                                DomReturnType drr = new DomReturnType (res.FullName);
275
343
                                                drr.PointerNestingLevel = type.PointerNestingLevel;
276
344
                                                drr.ArrayDimensions = type.ArrayDimensions;
277
 
                                                drr.Type  = type.Type; // May be anonymous type
 
345
                                                if (!(type.Type is ITypeParameterType))
 
346
                                                        drr.Type  = type.Type; // May be anonymous type
278
347
                                                for (int i = 0; i < type.ArrayDimensions; i++)
279
348
                                                        drr.SetDimension (i, type.GetDimension (i));
280
349
                                                return drr;
298
367
                        if (dom == null || type == null || Parameters.Count == 0 || !IsExtension) {
299
368
                                return null;
300
369
                        }
301
 
//                      Console.WriteLine ("Ext.Type: " + type);
302
370
                        string extensionTableKey = this.HelpUrl + "/" + type.FullName;
303
 
//                      Console.WriteLine ("table key:" + extensionTableKey);
 
371
                        if (Name.StartsWith ("ForEachWithIndex"))
 
372
                                Console.WriteLine ("table key:" + extensionTableKey);
304
373
                        lock (extensionTable) {
305
374
                                if (extensionTable.ContainsKey (extensionTableKey))
306
375
                                        return extensionTable[extensionTableKey];
324
393
                                        string baseTypeFullName = baseType is InstantiatedType ? ((InstantiatedType)baseType).UninstantiatedType.FullName : baseType.FullName;
325
394
                                        
326
395
                                        // compare the generic arguments.
327
 
                                        if (instMethod.Parameters[0].ReturnType.FullName == baseTypeFullName) {
 
396
                                        if (instMethod.Parameters[0].ReturnType.FullName == baseTypeFullName && Parameters[0].ReturnType.ArrayDimensions == 0 && Parameters[0].ReturnType.PointerNestingLevel == 0) {
328
397
                                                if (instMethod.Parameters[0].ReturnType.GenericArguments.Count > 0) {
329
398
                                                        InstantiatedType instType = baseType as InstantiatedType;
330
399
                                                        if (instType == null || instType.GenericParameters.Count != instMethod.Parameters[0].ReturnType.GenericArguments.Count)
331
400
                                                                continue;
332
401
                                                        bool genericArgumentsAreEqual = true;
333
402
                                                        for (int i = 0; i < instMethod.Parameters[0].ReturnType.GenericArguments.Count; i++) {
334
 
                                                                //Console.WriteLine (instMethod.Parameters[0].ReturnType.GenericArguments[i].DecoratedFullName + " --- " + instType.GenericParameters[i].DecoratedFullName);
 
403
                                                                if (Name.StartsWith ("ForEachWithIndex"))
 
404
                                                                        Console.WriteLine (instMethod.Parameters[0].ReturnType.GenericArguments[i].DecoratedFullName + " --- " + instType.GenericParameters[i].DecoratedFullName);
335
405
                                                                if (instMethod.Parameters[0].ReturnType.GenericArguments[i].DecoratedFullName != instType.GenericParameters[i].DecoratedFullName) {
336
406
                                                                        genericArgumentsAreEqual = false;
337
407
                                                                        break;
354
424
                        }
355
425
                }
356
426
                
357
 
                public void Add (IParameter parameter)
 
427
                public override void Add (IParameter parameter)
358
428
                {
359
429
                        if (parameters == null) 
360
430
                                parameters = new List<IParameter> ();
362
432
                        parameters.Add (parameter);
363
433
                }
364
434
                
365
 
                public void Add (IEnumerable<IParameter> parameters)
366
 
                {
367
 
                        if (parameters == null)
368
 
                                return;
369
 
                        foreach (IParameter parameter in parameters) {
370
 
                                Add (parameter);
371
 
                        }
372
 
                }
373
 
                
374
435
                XmlNode FindMatch (XmlNodeList nodes)
375
436
                {
376
437
                        List<IParameter> p = parameters ?? new List<IParameter> ();