~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.Collections.Generic;
 
6
using System.Runtime.Remoting.Messaging;
 
7
using System.Text;
 
8
using System.Linq;
 
9
using ICSharpCode.NRefactory;
 
10
using ICSharpCode.NRefactory.Ast;
 
11
using ICSharpCode.NRefactory.Visitors;
 
12
 
 
13
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
 
14
{
 
15
        /// <summary>
 
16
        /// Resolves expressions.
 
17
        /// </summary>
 
18
        sealed class ResolveVisitor : AbstractAstVisitor
 
19
        {
 
20
                NRefactoryResolver resolver;
 
21
                
 
22
                public ResolveVisitor(NRefactoryResolver resolver)
 
23
                {
 
24
                        this.resolver = resolver;
 
25
                }
 
26
                
 
27
                ResolveResult CreateResolveResult(TypeReference reference)
 
28
                {
 
29
                        return CreateResolveResult(TypeVisitor.CreateReturnType(reference, resolver));
 
30
                }
 
31
                
 
32
                ResolveResult CreateResolveResult(Expression expression)
 
33
                {
 
34
                        return CreateResolveResult(ResolveType(expression));
 
35
                }
 
36
                
 
37
                ResolveResult CreateResolveResult(IReturnType resolvedType)
 
38
                {
 
39
                        if (resolvedType == null)
 
40
                                return null;
 
41
                        else
 
42
                                return new ResolveResult(resolver.CallingClass, resolver.CallingMember, resolvedType);
 
43
                }
 
44
                
 
45
                TypeResolveResult CreateTypeResolveResult(IReturnType resolvedType)
 
46
                {
 
47
                        if (resolvedType == null) {
 
48
                                return null;
 
49
                        } else {
 
50
                                IReturnType rt = resolvedType;
 
51
                                while (rt != null && rt.IsArrayReturnType) {
 
52
                                        rt = rt.CastToArrayReturnType().ArrayElementType;
 
53
                                }
 
54
                                IClass resolvedClass = rt != null ? rt.GetUnderlyingClass() : null;
 
55
                                return new TypeResolveResult(resolver.CallingClass, resolver.CallingMember, resolvedType, resolvedClass);
 
56
                        }
 
57
                }
 
58
                
 
59
                MemberResolveResult CreateMemberResolveResult(IMember member)
 
60
                {
 
61
                        if (member == null)
 
62
                                return null;
 
63
                        else
 
64
                                return new MemberResolveResult(resolver.CallingClass, resolver.CallingMember, member);
 
65
                }
 
66
                
 
67
                readonly Dictionary<Expression, ResolveResult> cachedResults = new Dictionary<Expression, ResolveResult>();
 
68
                
 
69
                public ResolveResult Resolve(Expression expression)
 
70
                {
 
71
                        ResolveResult rr;
 
72
                        if (!cachedResults.TryGetValue(expression, out rr)) {
 
73
                                rr = (ResolveResult)expression.AcceptVisitor(this, null);
 
74
                                if (rr != null)
 
75
                                        rr.Freeze();
 
76
                                cachedResults[expression] = rr;
 
77
                        }
 
78
                        return rr;
 
79
                }
 
80
                
 
81
                public IReturnType ResolveType(Expression expression)
 
82
                {
 
83
                        ResolveResult rr = Resolve(expression);
 
84
                        if (rr != null)
 
85
                                return rr.ResolvedType;
 
86
                        else
 
87
                                return null;
 
88
                }
 
89
                
 
90
                public override object VisitAddressOfExpression(AddressOfExpression addressOfExpression, object data)
 
91
                {
 
92
                        bool oldValue = resolver.allowMethodGroupResolveResult;
 
93
                        resolver.allowMethodGroupResolveResult = true;
 
94
                        object result = base.VisitAddressOfExpression(addressOfExpression, data);
 
95
                        resolver.allowMethodGroupResolveResult = oldValue;
 
96
                        return result;
 
97
                }
 
98
                
 
99
                public override object VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, object data)
 
100
                {
 
101
                        return CreateResolveResult(new LambdaReturnType(anonymousMethodExpression, resolver));
 
102
                }
 
103
                
 
104
                public override object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data)
 
105
                {
 
106
                        if (arrayCreateExpression.IsImplicitlyTyped) {
 
107
                                return CreateResolveResult(arrayCreateExpression.ArrayInitializer);
 
108
                        } else {
 
109
                                return CreateTypeResolveResult(TypeVisitor.CreateReturnType(arrayCreateExpression.CreateType, resolver));
 
110
                        }
 
111
                }
 
112
                
 
113
                public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
 
114
                {
 
115
                        return CreateResolveResult(assignmentExpression.Left);
 
116
                }
 
117
                
 
118
                public override object VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, object data)
 
119
                {
 
120
                        if (resolver.CallingClass == null) {
 
121
                                return null;
 
122
                        }
 
123
                        if (resolver.Language == SupportedLanguage.VBNet && IsInstanceConstructor(resolver.CallingMember)) {
 
124
                                return new VBBaseOrThisReferenceInConstructorResolveResult(
 
125
                                        resolver.CallingClass, resolver.CallingMember, resolver.CallingClass.BaseType);
 
126
                        } else {
 
127
                                return new BaseResolveResult(resolver.CallingClass, resolver.CallingMember, resolver.CallingClass.BaseType);
 
128
                        }
 
129
                }
 
130
                
 
131
                public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
 
132
                {
 
133
                        switch (binaryOperatorExpression.Op) {
 
134
                                case BinaryOperatorType.NullCoalescing:
 
135
                                        return CreateResolveResult(binaryOperatorExpression.Right);
 
136
                                case BinaryOperatorType.DivideInteger:
 
137
                                        return CreateResolveResult(resolver.ProjectContent.SystemTypes.Int32);
 
138
                                case BinaryOperatorType.Concat:
 
139
                                        return CreateResolveResult(resolver.ProjectContent.SystemTypes.String);
 
140
                                case BinaryOperatorType.Equality:
 
141
                                case BinaryOperatorType.InEquality:
 
142
                                case BinaryOperatorType.ReferenceEquality:
 
143
                                case BinaryOperatorType.ReferenceInequality:
 
144
                                case BinaryOperatorType.LogicalAnd:
 
145
                                case BinaryOperatorType.LogicalOr:
 
146
                                case BinaryOperatorType.LessThan:
 
147
                                case BinaryOperatorType.LessThanOrEqual:
 
148
                                case BinaryOperatorType.GreaterThan:
 
149
                                case BinaryOperatorType.GreaterThanOrEqual:
 
150
                                        return CreateResolveResult(resolver.ProjectContent.SystemTypes.Boolean);
 
151
                                default:
 
152
                                        return CreateResolveResult(MemberLookupHelper.GetCommonType(
 
153
                                                resolver.ProjectContent,
 
154
                                                ResolveType(binaryOperatorExpression.Left),
 
155
                                                ResolveType(binaryOperatorExpression.Right)));
 
156
                        }
 
157
                }
 
158
                
 
159
                public override object VisitCastExpression(CastExpression castExpression, object data)
 
160
                {
 
161
                        return CreateResolveResult(castExpression.CastTo);
 
162
                }
 
163
                
 
164
                public override object VisitCheckedExpression(CheckedExpression checkedExpression, object data)
 
165
                {
 
166
                        return CreateResolveResult(checkedExpression.Expression);
 
167
                }
 
168
                
 
169
                public override object VisitClassReferenceExpression(ClassReferenceExpression classReferenceExpression, object data)
 
170
                {
 
171
                        if (resolver.CallingClass != null)
 
172
                                return CreateResolveResult(resolver.CallingClass.DefaultReturnType);
 
173
                        else
 
174
                                return null;
 
175
                }
 
176
                
 
177
                public override object VisitCollectionInitializerExpression(CollectionInitializerExpression collectionInitializerExpression, object data)
 
178
                {
 
179
                        // used for implicitly typed arrays
 
180
                        if (collectionInitializerExpression.CreateExpressions.Count == 0)
 
181
                                return null;
 
182
                        IReturnType combinedRT = ResolveType(collectionInitializerExpression.CreateExpressions[0]);
 
183
                        for (int i = 1; i < collectionInitializerExpression.CreateExpressions.Count; i++) {
 
184
                                IReturnType rt = ResolveType(collectionInitializerExpression.CreateExpressions[i]);
 
185
                                combinedRT = MemberLookupHelper.GetCommonType(resolver.ProjectContent, combinedRT, rt);
 
186
                        }
 
187
                        if (combinedRT == null)
 
188
                                return null;
 
189
                        return CreateResolveResult(new ArrayReturnType(resolver.ProjectContent, combinedRT, 1));
 
190
                }
 
191
                
 
192
                public override object VisitConditionalExpression(ConditionalExpression conditionalExpression, object data)
 
193
                {
 
194
                        return CreateResolveResult(MemberLookupHelper.GetCommonType(
 
195
                                resolver.ProjectContent,
 
196
                                ResolveType(conditionalExpression.TrueExpression),
 
197
                                ResolveType(conditionalExpression.FalseExpression)));
 
198
                }
 
199
                
 
200
                public override object VisitConstructorInitializer(ConstructorInitializer constructorInitializer, object data)
 
201
                {
 
202
                        return null;
 
203
                }
 
204
                
 
205
                public override object VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, object data)
 
206
                {
 
207
                        return CreateResolveResult(defaultValueExpression.TypeReference);
 
208
                }
 
209
                
 
210
                public override object VisitDirectionExpression(DirectionExpression directionExpression, object data)
 
211
                {
 
212
                        return CreateResolveResult(new ReferenceReturnType(ResolveType(directionExpression.Expression)));
 
213
                }
 
214
                
 
215
                public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
 
216
                {
 
217
                        return resolver.ResolveIdentifier(identifierExpression, ExpressionContext.Default);
 
218
                }
 
219
                
 
220
                public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
 
221
                {
 
222
                        IReturnType target = ResolveType(indexerExpression.TargetObject);
 
223
                        return CreateMemberResolveResult(
 
224
                                GetIndexer(target, indexerExpression.Indexes)
 
225
                        );
 
226
                }
 
227
                
 
228
                IProperty GetIndexer(IReturnType target, List<Expression> indexes)
 
229
                {
 
230
                        if (target == null)
 
231
                                return null;
 
232
                        return MemberLookupHelper.FindOverload(
 
233
                                target.GetProperties().Where((IProperty p) => p.IsIndexer).ToList(),
 
234
                                indexes.Select<Expression, IReturnType>(ResolveType).ToArray()
 
235
                        );
 
236
                }
 
237
                
 
238
                IProperty GetVisualBasicIndexer(InvocationExpression invocationExpression)
 
239
                {
 
240
                        ResolveResult targetRR = Resolve(invocationExpression.TargetObject);
 
241
                        if (targetRR != null) {
 
242
                                // Visual Basic can call indexers in two ways:
 
243
                                // collection(index) - use indexer
 
244
                                // collection.Item(index) - use parametrized property
 
245
                                
 
246
                                if (invocationExpression.TargetObject is IdentifierExpression || invocationExpression.TargetObject is MemberReferenceExpression) {
 
247
                                        // only IdentifierExpression/MemberReferenceExpression can represent a parametrized property
 
248
                                        // - the check is necessary because collection.Items and collection.Item(index) both
 
249
                                        // resolve to the same property, but we want to use the default indexer for the second call in
 
250
                                        // collection.Item(index1)(index2)
 
251
                                        MemberResolveResult memberRR = targetRR as MemberResolveResult;
 
252
                                        if (memberRR != null)  {
 
253
                                                IProperty p = memberRR.ResolvedMember as IProperty;
 
254
                                                if (p != null && p.Parameters.Count > 0) {
 
255
                                                        // this is a parametrized property
 
256
                                                        return p;
 
257
                                                }
 
258
                                        }
 
259
                                }
 
260
                                // not a parametrized property - try normal indexer
 
261
                                return GetIndexer(targetRR.ResolvedType, invocationExpression.Arguments);
 
262
                        } else {
 
263
                                return null;
 
264
                        }
 
265
                }
 
266
                
 
267
                public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
 
268
                {
 
269
                        if (resolver.Language == SupportedLanguage.CSharp && resolver.CallingClass != null) {
 
270
                                if (invocationExpression.TargetObject is ThisReferenceExpression) {
 
271
                                        // call to constructor
 
272
                                        return ResolveConstructorOverload(resolver.CallingClass, invocationExpression.Arguments);
 
273
                                } else if (invocationExpression.TargetObject is BaseReferenceExpression) {
 
274
                                        return ResolveConstructorOverload(resolver.CallingClass.BaseType, invocationExpression.Arguments);
 
275
                                }
 
276
                        }
 
277
                        
 
278
                        ResolveResult rr = Resolve(invocationExpression.TargetObject);
 
279
                        MixedResolveResult mixedRR = rr as MixedResolveResult;
 
280
                        if (mixedRR != null) {
 
281
                                rr = mixedRR.PrimaryResult;
 
282
                        }
 
283
                        MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;
 
284
                        if (mgrr != null) {
 
285
                                if (resolver.Language == SupportedLanguage.VBNet) {
 
286
                                        if (mgrr.Methods.All(mg => mg.Count == 0))
 
287
                                                return CreateMemberResolveResult(GetVisualBasicIndexer(invocationExpression));
 
288
//                                      IMethod empty = mgrr.GetMethodWithEmptyParameterList();
 
289
//                                      if (empty != null)
 
290
//                                              return CreateMemberResolveResult(empty);
 
291
                                }
 
292
                                
 
293
                                IReturnType[] argumentTypes = invocationExpression.Arguments.Select<Expression, IReturnType>(ResolveType).ToArray();
 
294
                                
 
295
                                MemberResolveResult firstResult = null;
 
296
                                foreach (MethodGroup methodGroup in mgrr.Methods) {
 
297
                                        bool resultIsAcceptable;
 
298
                                        IMethod method;
 
299
                                        if (methodGroup.IsExtensionMethodGroup) {
 
300
                                                IReturnType[] extendedTypes = new IReturnType[argumentTypes.Length + 1];
 
301
                                                extendedTypes[0] = mgrr.ContainingType;
 
302
                                                argumentTypes.CopyTo(extendedTypes, 1);
 
303
                                                method = MemberLookupHelper.FindOverload(methodGroup, extendedTypes, out resultIsAcceptable);
 
304
                                        } else {
 
305
                                                method = MemberLookupHelper.FindOverload(methodGroup, argumentTypes, out resultIsAcceptable);
 
306
                                        }
 
307
                                        MemberResolveResult result = CreateMemberResolveResult(method);
 
308
                                        if (result != null && methodGroup.IsExtensionMethodGroup)
 
309
                                                result.IsExtensionMethodCall = true;
 
310
                                        if (resultIsAcceptable)
 
311
                                                return result;
 
312
                                        if (firstResult == null)
 
313
                                                firstResult = result;
 
314
                                }
 
315
                                if (firstResult != null) {
 
316
                                        return firstResult;
 
317
                                } else {
 
318
                                        return FallbackResolveMethod(invocationExpression, mgrr, argumentTypes);
 
319
                                }
 
320
                        } else if (rr != null && rr.ResolvedType != null) {
 
321
                                IClass c = rr.ResolvedType.GetUnderlyingClass();
 
322
                                if (c != null && c.ClassType == ClassType.Delegate) {
 
323
                                        // We don't want to show "System.EventHandler.Invoke" in the tooltip
 
324
                                        // of "EventCall(this, EventArgs.Empty)", we just show the event/delegate for now
 
325
                                        // but for DelegateCall(params).* completion, we use the delegate's
 
326
                                        // return type instead of the delegate type itself
 
327
                                        
 
328
                                        IMethod method = rr.ResolvedType.GetMethods().FirstOrDefault(innerMethod => innerMethod.Name == "Invoke");
 
329
                                        if (method != null) {
 
330
                                                return new DelegateCallResolveResult(rr, method);
 
331
                                        }
 
332
                                }
 
333
                        }
 
334
                        if (resolver.Language == SupportedLanguage.VBNet) {
 
335
                                return CreateMemberResolveResult(GetVisualBasicIndexer(invocationExpression));
 
336
                        }
 
337
 
 
338
                        return resolver.CreateUnknownMethodResolveResult(invocationExpression);
 
339
                }
 
340
                
 
341
                ResolveResult FallbackResolveMethod(InvocationExpression invocation, MethodGroupResolveResult mgrr, IReturnType[] argumentTypes)
 
342
                {
 
343
                        // method not found, let's try if we can find a method if we violate the
 
344
                        // accessibility rules
 
345
                        MemberReferenceExpression mre = invocation.TargetObject as MemberReferenceExpression;
 
346
                        if (mre != null) {
 
347
                                List<IMethod> methods = mgrr.ContainingType.GetMethods().Where(m => resolver.IsSameName(m.Name, mre.MemberName)).ToList();
 
348
                                bool resultIsAcceptable;
 
349
                                IMethod result = MemberLookupHelper.FindOverload(
 
350
                                        methods, argumentTypes, out resultIsAcceptable);
 
351
                                if (result != null) {
 
352
                                        return CreateMemberResolveResult(result);
 
353
                                }
 
354
                        }
 
355
                        
 
356
                        return resolver.CreateUnknownMethodResolveResult(invocation);
 
357
                }
 
358
                
 
359
                public override object VisitLambdaExpression(LambdaExpression lambdaExpression, object data)
 
360
                {
 
361
                        return CreateResolveResult(new LambdaReturnType(lambdaExpression, resolver));
 
362
                }
 
363
                
 
364
                public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
 
365
                {
 
366
                        IReturnType type;
 
367
                        if (string.IsNullOrEmpty(memberReferenceExpression.MemberName)) {
 
368
                                // NRefactory creates this "dummy" fieldReferenceExpression when it should
 
369
                                // parse a primitive type name (int, short; Integer, Decimal)
 
370
                                if (memberReferenceExpression.TargetObject is TypeReferenceExpression) {
 
371
                                        type = TypeVisitor.CreateReturnType(((TypeReferenceExpression)memberReferenceExpression.TargetObject).TypeReference, resolver);
 
372
                                        return CreateTypeResolveResult(type);
 
373
                                }
 
374
                        }
 
375
                        ResolveResult targetRR = Resolve(memberReferenceExpression.TargetObject);
 
376
                        if (targetRR == null)
 
377
                                return null;
 
378
 
 
379
                        type = GetType(targetRR);
 
380
                        if (targetRR is NamespaceResolveResult) {
 
381
                                return ResolveMemberInNamespace(((NamespaceResolveResult)targetRR).Name, memberReferenceExpression);
 
382
                        } else if (type != null) {
 
383
                                TypeResolveResult typeRR = targetRR as TypeResolveResult;
 
384
                                if (typeRR != null && typeRR.ResolvedClass != null) {
 
385
                                        foreach (IClass c1 in typeRR.ResolvedClass.ClassInheritanceTree) {
 
386
                                                foreach (IClass c in c1.InnerClasses) {
 
387
                                                        if (resolver.IsSameName(memberReferenceExpression.MemberName, c.Name)
 
388
                                                            && c.TypeParameters.Count == memberReferenceExpression.TypeArguments.Count)
 
389
                                                        {
 
390
                                                                return CreateTypeResolveResult(resolver.ConstructType(c.DefaultReturnType, memberReferenceExpression.TypeArguments));
 
391
                                                        }
 
392
                                                }
 
393
                                        }
 
394
                                }
 
395
                                
 
396
                                var memberRR = resolver.ResolveMember(type, memberReferenceExpression.MemberName,
 
397
                                                                      memberReferenceExpression.TypeArguments,
 
398
                                                                      NRefactoryResolver.IsInvoked(memberReferenceExpression),
 
399
                                                                      typeRR == null, // allow extension methods only for non-static method calls
 
400
                                                                      targetRR is BaseResolveResult ? (bool?)true : null // allow calling protected members using "base."
 
401
                                                                     );
 
402
                                
 
403
//                              MethodGroupResolveResult mgRR = memberRR as MethodGroupResolveResult;
 
404
//
 
405
//                              if (mgRR == null)
 
406
//                                      mgRR = targetRR as MethodGroupResolveResult;
 
407
//
 
408
//                              if (mgRR != null && !resolver.allowMethodGroupResolveResult)
 
409
//                                      return CreateMemberResolveResult(mgRR.GetMethodWithEmptyParameterList());
 
410
                                
 
411
                                return memberRR;
 
412
                        }
 
413
                        return null;
 
414
                }
 
415
                
 
416
                IReturnType GetType(ResolveResult targetRR)
 
417
                {
 
418
                        if (targetRR.ResolvedType != null)
 
419
                                return targetRR.ResolvedType;
 
420
                        
 
421
                        if (targetRR is MixedResolveResult && ((MixedResolveResult)targetRR).TypeResult != null)
 
422
                                return ((MixedResolveResult)targetRR).TypeResult.ResolvedType;
 
423
                        
 
424
                        return null;
 
425
                }
 
426
                
 
427
                ResolveResult ResolveMemberInNamespace(string namespaceName, MemberReferenceExpression mre)
 
428
                {
 
429
                        string combinedName;
 
430
                        if (string.IsNullOrEmpty(namespaceName))
 
431
                                combinedName = mre.MemberName;
 
432
                        else
 
433
                                combinedName = namespaceName + "." + mre.MemberName;
 
434
                        if (resolver.ProjectContent.NamespaceExists(combinedName)) {
 
435
                                return new NamespaceResolveResult(resolver.CallingClass, resolver.CallingMember, combinedName);
 
436
                        }
 
437
                        IClass c = resolver.GetClass(combinedName, mre.TypeArguments.Count);
 
438
                        if (c != null) {
 
439
                                return CreateTypeResolveResult(resolver.ConstructType(c.DefaultReturnType, mre.TypeArguments));
 
440
                        }
 
441
                        if (resolver.LanguageProperties.ImportModules) {
 
442
                                // go through the members of the modules
 
443
                                List<IMember> possibleMembers = new List<IMember>();
 
444
                                foreach (object o in resolver.ProjectContent.GetNamespaceContents(namespaceName)) {
 
445
                                        IMember member = o as IMember;
 
446
                                        if (member != null && resolver.IsSameName(member.Name, mre.MemberName)) {
 
447
                                                possibleMembers.Add(member);
 
448
                                        }
 
449
                                }
 
450
                                return resolver.CreateMemberOrMethodGroupResolveResult(
 
451
                                        null, mre.MemberName, new IList<IMember>[] { possibleMembers }, false, null);
 
452
                        }
 
453
                        return null;
 
454
                }
 
455
                
 
456
                public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
 
457
                {
 
458
                        if (objectCreateExpression.IsAnonymousType) {
 
459
                                return CreateResolveResult(CreateAnonymousTypeClass(objectCreateExpression.ObjectInitializer).DefaultReturnType);
 
460
                        } else {
 
461
                                IReturnType rt = TypeVisitor.CreateReturnType(objectCreateExpression.CreateType, resolver);
 
462
                                if (rt == null)
 
463
                                        return new UnknownConstructorCallResolveResult(resolver.CallingClass, resolver.CallingMember, objectCreateExpression.CreateType.ToString());
 
464
                                
 
465
                                return ResolveConstructorOverload(rt, objectCreateExpression.Parameters)
 
466
                                        ?? CreateResolveResult(rt);
 
467
                        }
 
468
                }
 
469
                
 
470
                internal ResolveResult ResolveConstructorOverload(IReturnType rt, List<Expression> arguments)
 
471
                {
 
472
                        if (rt == null)
 
473
                                return null;
 
474
                        
 
475
                        List<IMethod> methods = rt.GetMethods().Where(m => m.IsConstructor && !m.IsStatic).ToList();
 
476
                        IReturnType[] argumentTypes = arguments.Select<Expression, IReturnType>(ResolveType).ToArray();
 
477
                        bool resultIsAcceptable;
 
478
                        IMethod result = MemberLookupHelper.FindOverload(methods, argumentTypes, out resultIsAcceptable);
 
479
                        
 
480
                        ResolveResult rr = CreateMemberResolveResult(result);
 
481
                        if (rr != null)
 
482
                                rr.ResolvedType = rt;
 
483
                        return rr;
 
484
                }
 
485
                
 
486
                internal ResolveResult ResolveConstructorOverload(IClass c, List<Expression> arguments)
 
487
                {
 
488
                        if (c == null)
 
489
                                return null;
 
490
                        else
 
491
                                return ResolveConstructorOverload(c.DefaultReturnType, arguments);
 
492
                }
 
493
                
 
494
                DefaultClass CreateAnonymousTypeClass(CollectionInitializerExpression initializer)
 
495
                {
 
496
                        List<IReturnType> fieldTypes = new List<IReturnType>();
 
497
                        List<string> fieldNames = new List<string>();
 
498
                        
 
499
                        foreach (Expression expr in initializer.CreateExpressions) {
 
500
                                if (expr is MemberInitializerExpression) {
 
501
                                        // use right part only
 
502
                                        fieldTypes.Add( ResolveType(((MemberInitializerExpression)expr).Expression) );
 
503
                                } else {
 
504
                                        fieldTypes.Add( ResolveType(expr) );
 
505
                                }
 
506
                                
 
507
                                fieldNames.Add(GetAnonymousTypeFieldName(expr));
 
508
                        }
 
509
                        
 
510
                        StringBuilder nameBuilder = new StringBuilder();
 
511
                        nameBuilder.Append('{');
 
512
                        for (int i = 0; i < fieldTypes.Count; i++) {
 
513
                                if (i > 0) nameBuilder.Append(", ");
 
514
                                nameBuilder.Append(fieldNames[i]);
 
515
                                nameBuilder.Append(" : ");
 
516
                                if (fieldTypes[i] != null) {
 
517
                                        nameBuilder.Append(fieldTypes[i].DotNetName);
 
518
                                }
 
519
                        }
 
520
                        nameBuilder.Append('}');
 
521
                        
 
522
                        DefaultClass c = new DefaultClass(new DefaultCompilationUnit(resolver.ProjectContent), nameBuilder.ToString());
 
523
                        c.Modifiers = ModifierEnum.Internal | ModifierEnum.Synthetic | ModifierEnum.Sealed;
 
524
                        for (int i = 0; i < fieldTypes.Count; i++) {
 
525
                                DefaultProperty p = new DefaultProperty(fieldNames[i], fieldTypes[i], ModifierEnum.Public | ModifierEnum.Synthetic, DomRegion.Empty, DomRegion.Empty, c);
 
526
                                p.CanGet = true;
 
527
                                p.CanSet = false;
 
528
                                c.Properties.Add(p);
 
529
                        }
 
530
                        return c;
 
531
                }
 
532
                
 
533
                static string GetAnonymousTypeFieldName(Expression expr)
 
534
                {
 
535
                        if (expr is MemberReferenceExpression) {
 
536
                                return ((MemberReferenceExpression)expr).MemberName;
 
537
                        } else if (expr is MemberInitializerExpression) {
 
538
                                return ((MemberInitializerExpression)expr).Name;
 
539
                        } else if (expr is IdentifierExpression) {
 
540
                                return ((IdentifierExpression)expr).Identifier;
 
541
                        } else {
 
542
                                return "?";
 
543
                        }
 
544
                }
 
545
                
 
546
                public override object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data)
 
547
                {
 
548
                        return CreateResolveResult(parenthesizedExpression.Expression);
 
549
                }
 
550
                
 
551
                public override object VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, object data)
 
552
                {
 
553
                        ResolveResult targetRR = Resolve(pointerReferenceExpression.TargetObject);
 
554
                        if (targetRR == null || targetRR.ResolvedType == null)
 
555
                                return null;
 
556
                        PointerReturnType type = targetRR.ResolvedType.CastToDecoratingReturnType<PointerReturnType>();
 
557
                        if (type != null) {
 
558
                                return resolver.ResolveMember(type.BaseType, pointerReferenceExpression.MemberName,
 
559
                                                              pointerReferenceExpression.TypeArguments,
 
560
                                                              NRefactoryResolver.IsInvoked(pointerReferenceExpression),
 
561
                                                              true, null
 
562
                                                             );
 
563
                        }
 
564
                        return null;
 
565
                }
 
566
                
 
567
                public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
 
568
                {
 
569
                        if (primitiveExpression.Value == null) {
 
570
                                return CreateResolveResult(NullReturnType.Instance);
 
571
                        } else if (primitiveExpression.Value is int) {
 
572
                                return new IntegerLiteralResolveResult(resolver.CallingClass, resolver.CallingMember, resolver.ProjectContent.SystemTypes.Int32);
 
573
                        } else {
 
574
                                return CreateResolveResult(resolver.ProjectContent.SystemTypes.CreatePrimitive(primitiveExpression.Value.GetType()));
 
575
                        }
 
576
                }
 
577
                
 
578
                public override object VisitQueryExpression(QueryExpression queryExpression, object data)
 
579
                {
 
580
                        QueryExpressionSelectClause selectClause = queryExpression.SelectOrGroupClause as QueryExpressionSelectClause;
 
581
                        QueryExpressionGroupClause groupClause = queryExpression.SelectOrGroupClause as QueryExpressionGroupClause;
 
582
                        if (selectClause != null) {
 
583
                                // Fake a call to 'Select'
 
584
                                var fakeInvocation = new InvocationExpression(new MemberReferenceExpression(
 
585
                                        queryExpression.FromClause.Sources.First().Expression, "Select"));
 
586
                                
 
587
                                var selector = new LambdaExpression();
 
588
                                selector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
 
589
                                selector.ExpressionBody = selectClause.Projection;
 
590
                                selector.Parent = fakeInvocation;
 
591
                                
 
592
                                fakeInvocation.Arguments.Add(selector);
 
593
                                
 
594
                                return CreateResolveResult(ResolveType(fakeInvocation));
 
595
                        } else if (groupClause != null) {
 
596
                                // Fake a call to 'GroupBy'
 
597
                                var fakeInvocation = new InvocationExpression(new MemberReferenceExpression(
 
598
                                        queryExpression.FromClause.Sources.First().Expression, "GroupBy"));
 
599
                                
 
600
                                var keySelector = new LambdaExpression();
 
601
                                keySelector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
 
602
                                keySelector.ExpressionBody = groupClause.GroupBy;
 
603
                                keySelector.Parent = fakeInvocation;
 
604
                                
 
605
                                var elementSelector = new LambdaExpression();
 
606
                                elementSelector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
 
607
                                elementSelector.ExpressionBody = groupClause.Projection;
 
608
                                elementSelector.Parent = fakeInvocation;
 
609
                                
 
610
                                fakeInvocation.Arguments.Add(keySelector);
 
611
                                fakeInvocation.Arguments.Add(elementSelector);
 
612
                                
 
613
                                return CreateResolveResult(ResolveType(fakeInvocation));
 
614
                        } else {
 
615
                                return null;
 
616
                        }
 
617
                }
 
618
                
 
619
                public override object VisitSizeOfExpression(SizeOfExpression sizeOfExpression, object data)
 
620
                {
 
621
                        return CreateResolveResult(resolver.ProjectContent.SystemTypes.Int32);
 
622
                }
 
623
                
 
624
                public override object VisitStackAllocExpression(StackAllocExpression stackAllocExpression, object data)
 
625
                {
 
626
                        return null;
 
627
                }
 
628
                
 
629
                public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
 
630
                {
 
631
                        if (resolver.CallingClass == null)
 
632
                                return null;
 
633
                        if (resolver.Language == SupportedLanguage.VBNet && IsInstanceConstructor(resolver.CallingMember)) {
 
634
                                return new VBBaseOrThisReferenceInConstructorResolveResult(
 
635
                                        resolver.CallingClass, resolver.CallingMember, resolver.CallingClass.DefaultReturnType);
 
636
                        } else {
 
637
                                return CreateResolveResult(resolver.CallingClass.DefaultReturnType);
 
638
                        }
 
639
                }
 
640
                
 
641
                static bool IsInstanceConstructor(IMember member)
 
642
                {
 
643
                        IMethod m = member as IMethod;
 
644
                        return m != null && m.IsConstructor && !m.IsStatic;
 
645
                }
 
646
                
 
647
                public override object VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data)
 
648
                {
 
649
                        return CreateResolveResult(resolver.ProjectContent.SystemTypes.Type);
 
650
                }
 
651
                
 
652
                public override object VisitTypeOfIsExpression(TypeOfIsExpression typeOfIsExpression, object data)
 
653
                {
 
654
                        return CreateResolveResult(resolver.ProjectContent.SystemTypes.Boolean);
 
655
                }
 
656
                
 
657
                public override object VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data)
 
658
                {
 
659
                        TypeReference reference = typeReferenceExpression.TypeReference;
 
660
                        ResolveResult rr = CreateTypeResolveResult(TypeVisitor.CreateReturnType(reference, resolver));
 
661
                        if (rr == null && reference.GenericTypes.Count == 0 && !reference.IsArrayType) {
 
662
                                // reference to namespace is possible
 
663
                                if (reference.IsGlobal) {
 
664
                                        if (resolver.ProjectContent.NamespaceExists(reference.Type))
 
665
                                                return new NamespaceResolveResult(resolver.CallingClass, resolver.CallingMember, reference.Type);
 
666
                                } else {
 
667
                                        string name = resolver.SearchNamespace(reference.Type, typeReferenceExpression.StartLocation);
 
668
                                        if (name != null)
 
669
                                                return new NamespaceResolveResult(resolver.CallingClass, resolver.CallingMember, name);
 
670
                                }
 
671
                        }
 
672
                        if (rr != null) {
 
673
                                return rr;
 
674
                        } else {
 
675
                                return new UnknownIdentifierResolveResult(resolver.CallingClass, resolver.CallingMember, reference.Type);
 
676
                        }
 
677
                }
 
678
                
 
679
                public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)
 
680
                {
 
681
                        IReturnType type = ResolveType(unaryOperatorExpression.Expression);
 
682
                        if (type == null)
 
683
                                return null;
 
684
                        switch (unaryOperatorExpression.Op) {
 
685
                                case UnaryOperatorType.AddressOf:
 
686
                                        return CreateResolveResult(new PointerReturnType(type));
 
687
                                case UnaryOperatorType.Dereference:
 
688
                                        PointerReturnType prt = type.CastToDecoratingReturnType<PointerReturnType>();
 
689
                                        if (prt != null) {
 
690
                                                return CreateResolveResult(prt.BaseType);
 
691
                                        } else {
 
692
                                                return null;
 
693
                                        }
 
694
                                default:
 
695
                                        return CreateResolveResult(type);
 
696
                        }
 
697
                }
 
698
                
 
699
                public override object VisitUncheckedExpression(UncheckedExpression uncheckedExpression, object data)
 
700
                {
 
701
                        return CreateResolveResult(uncheckedExpression.Expression);
 
702
                }
 
703
                
 
704
                #region XML Literal resolver
 
705
                public override object VisitXmlContentExpression(XmlContentExpression xmlContentExpression, object data)
 
706
                {
 
707
                        switch (xmlContentExpression.Type) {
 
708
                                case XmlContentType.Comment:
 
709
                                        return CreateResolveResult(new TypeReference("System.Xml.Linq.XComment"));
 
710
                                case XmlContentType.Text:
 
711
                                        return CreateResolveResult(new TypeReference("System.Xml.Linq.XText"));
 
712
                                case XmlContentType.CData:
 
713
                                        return CreateResolveResult(new TypeReference("System.Xml.Linq.XCData"));
 
714
                                case XmlContentType.ProcessingInstruction:
 
715
                                        if (xmlContentExpression.Content.StartsWith("xml ", StringComparison.OrdinalIgnoreCase))
 
716
                                                return CreateResolveResult(new TypeReference("System.Xml.Linq.XDocumentType"));
 
717
                                        return CreateResolveResult(new TypeReference("System.Xml.Linq.XProcessingInstruction"));
 
718
                                default:
 
719
                                        throw new Exception("Invalid value for XmlContentType");
 
720
                        }
 
721
                }
 
722
                
 
723
                public override object VisitXmlDocumentExpression(XmlDocumentExpression xmlDocumentExpression, object data)
 
724
                {
 
725
                        return CreateResolveResult(new TypeReference("System.Xml.Linq.XDocument"));
 
726
                }
 
727
                
 
728
                public override object VisitXmlElementExpression(XmlElementExpression xmlElementExpression, object data)
 
729
                {
 
730
                        return CreateResolveResult(new TypeReference("System.Xml.Linq.XElement"));
 
731
                }
 
732
                
 
733
                public override object VisitXmlMemberAccessExpression(XmlMemberAccessExpression xmlMemberAccessExpression, object data)
 
734
                {
 
735
                        switch (xmlMemberAccessExpression.AxisType) {
 
736
                                case XmlAxisType.Element:
 
737
                                case XmlAxisType.Descendents:
 
738
                                        return CreateResolveResult(
 
739
                                                new TypeReference("System.Collections.Generic.IEnumerable",
 
740
                                                                  new List<TypeReference> { new TypeReference("System.Xml.Linq.XElement") { IsGlobal = true } }
 
741
                                                                 ) { IsGlobal = true }
 
742
                                        );
 
743
                                case XmlAxisType.Attribute:
 
744
                                        return CreateResolveResult(new TypeReference("System.String", true) { IsGlobal = true });
 
745
                                default:
 
746
                                        throw new Exception("Invalid value for XmlAxisType");
 
747
                        }
 
748
                }
 
749
                #endregion
 
750
        }
 
751
}