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)
5
using System.Collections.Generic;
6
using System.Runtime.Remoting.Messaging;
9
using ICSharpCode.NRefactory;
10
using ICSharpCode.NRefactory.Ast;
11
using ICSharpCode.NRefactory.Visitors;
13
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
16
/// Resolves expressions.
18
sealed class ResolveVisitor : AbstractAstVisitor
20
NRefactoryResolver resolver;
22
public ResolveVisitor(NRefactoryResolver resolver)
24
this.resolver = resolver;
27
ResolveResult CreateResolveResult(TypeReference reference)
29
return CreateResolveResult(TypeVisitor.CreateReturnType(reference, resolver));
32
ResolveResult CreateResolveResult(Expression expression)
34
return CreateResolveResult(ResolveType(expression));
37
ResolveResult CreateResolveResult(IReturnType resolvedType)
39
if (resolvedType == null)
42
return new ResolveResult(resolver.CallingClass, resolver.CallingMember, resolvedType);
45
TypeResolveResult CreateTypeResolveResult(IReturnType resolvedType)
47
if (resolvedType == null) {
50
IReturnType rt = resolvedType;
51
while (rt != null && rt.IsArrayReturnType) {
52
rt = rt.CastToArrayReturnType().ArrayElementType;
54
IClass resolvedClass = rt != null ? rt.GetUnderlyingClass() : null;
55
return new TypeResolveResult(resolver.CallingClass, resolver.CallingMember, resolvedType, resolvedClass);
59
MemberResolveResult CreateMemberResolveResult(IMember member)
64
return new MemberResolveResult(resolver.CallingClass, resolver.CallingMember, member);
67
readonly Dictionary<Expression, ResolveResult> cachedResults = new Dictionary<Expression, ResolveResult>();
69
public ResolveResult Resolve(Expression expression)
72
if (!cachedResults.TryGetValue(expression, out rr)) {
73
rr = (ResolveResult)expression.AcceptVisitor(this, null);
76
cachedResults[expression] = rr;
81
public IReturnType ResolveType(Expression expression)
83
ResolveResult rr = Resolve(expression);
85
return rr.ResolvedType;
90
public override object VisitAddressOfExpression(AddressOfExpression addressOfExpression, object data)
92
bool oldValue = resolver.allowMethodGroupResolveResult;
93
resolver.allowMethodGroupResolveResult = true;
94
object result = base.VisitAddressOfExpression(addressOfExpression, data);
95
resolver.allowMethodGroupResolveResult = oldValue;
99
public override object VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, object data)
101
return CreateResolveResult(new LambdaReturnType(anonymousMethodExpression, resolver));
104
public override object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data)
106
if (arrayCreateExpression.IsImplicitlyTyped) {
107
return CreateResolveResult(arrayCreateExpression.ArrayInitializer);
109
return CreateTypeResolveResult(TypeVisitor.CreateReturnType(arrayCreateExpression.CreateType, resolver));
113
public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
115
return CreateResolveResult(assignmentExpression.Left);
118
public override object VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, object data)
120
if (resolver.CallingClass == null) {
123
if (resolver.Language == SupportedLanguage.VBNet && IsInstanceConstructor(resolver.CallingMember)) {
124
return new VBBaseOrThisReferenceInConstructorResolveResult(
125
resolver.CallingClass, resolver.CallingMember, resolver.CallingClass.BaseType);
127
return new BaseResolveResult(resolver.CallingClass, resolver.CallingMember, resolver.CallingClass.BaseType);
131
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
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);
152
return CreateResolveResult(MemberLookupHelper.GetCommonType(
153
resolver.ProjectContent,
154
ResolveType(binaryOperatorExpression.Left),
155
ResolveType(binaryOperatorExpression.Right)));
159
public override object VisitCastExpression(CastExpression castExpression, object data)
161
return CreateResolveResult(castExpression.CastTo);
164
public override object VisitCheckedExpression(CheckedExpression checkedExpression, object data)
166
return CreateResolveResult(checkedExpression.Expression);
169
public override object VisitClassReferenceExpression(ClassReferenceExpression classReferenceExpression, object data)
171
if (resolver.CallingClass != null)
172
return CreateResolveResult(resolver.CallingClass.DefaultReturnType);
177
public override object VisitCollectionInitializerExpression(CollectionInitializerExpression collectionInitializerExpression, object data)
179
// used for implicitly typed arrays
180
if (collectionInitializerExpression.CreateExpressions.Count == 0)
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);
187
if (combinedRT == null)
189
return CreateResolveResult(new ArrayReturnType(resolver.ProjectContent, combinedRT, 1));
192
public override object VisitConditionalExpression(ConditionalExpression conditionalExpression, object data)
194
return CreateResolveResult(MemberLookupHelper.GetCommonType(
195
resolver.ProjectContent,
196
ResolveType(conditionalExpression.TrueExpression),
197
ResolveType(conditionalExpression.FalseExpression)));
200
public override object VisitConstructorInitializer(ConstructorInitializer constructorInitializer, object data)
205
public override object VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, object data)
207
return CreateResolveResult(defaultValueExpression.TypeReference);
210
public override object VisitDirectionExpression(DirectionExpression directionExpression, object data)
212
return CreateResolveResult(new ReferenceReturnType(ResolveType(directionExpression.Expression)));
215
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
217
return resolver.ResolveIdentifier(identifierExpression, ExpressionContext.Default);
220
public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
222
IReturnType target = ResolveType(indexerExpression.TargetObject);
223
return CreateMemberResolveResult(
224
GetIndexer(target, indexerExpression.Indexes)
228
IProperty GetIndexer(IReturnType target, List<Expression> indexes)
232
return MemberLookupHelper.FindOverload(
233
target.GetProperties().Where((IProperty p) => p.IsIndexer).ToList(),
234
indexes.Select<Expression, IReturnType>(ResolveType).ToArray()
238
IProperty GetVisualBasicIndexer(InvocationExpression invocationExpression)
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
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
260
// not a parametrized property - try normal indexer
261
return GetIndexer(targetRR.ResolvedType, invocationExpression.Arguments);
267
public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
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);
278
ResolveResult rr = Resolve(invocationExpression.TargetObject);
279
MixedResolveResult mixedRR = rr as MixedResolveResult;
280
if (mixedRR != null) {
281
rr = mixedRR.PrimaryResult;
283
MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;
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);
293
IReturnType[] argumentTypes = invocationExpression.Arguments.Select<Expression, IReturnType>(ResolveType).ToArray();
295
MemberResolveResult firstResult = null;
296
foreach (MethodGroup methodGroup in mgrr.Methods) {
297
bool resultIsAcceptable;
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);
305
method = MemberLookupHelper.FindOverload(methodGroup, argumentTypes, out resultIsAcceptable);
307
MemberResolveResult result = CreateMemberResolveResult(method);
308
if (result != null && methodGroup.IsExtensionMethodGroup)
309
result.IsExtensionMethodCall = true;
310
if (resultIsAcceptable)
312
if (firstResult == null)
313
firstResult = result;
315
if (firstResult != null) {
318
return FallbackResolveMethod(invocationExpression, mgrr, argumentTypes);
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
328
IMethod method = rr.ResolvedType.GetMethods().FirstOrDefault(innerMethod => innerMethod.Name == "Invoke");
329
if (method != null) {
330
return new DelegateCallResolveResult(rr, method);
334
if (resolver.Language == SupportedLanguage.VBNet) {
335
return CreateMemberResolveResult(GetVisualBasicIndexer(invocationExpression));
338
return resolver.CreateUnknownMethodResolveResult(invocationExpression);
341
ResolveResult FallbackResolveMethod(InvocationExpression invocation, MethodGroupResolveResult mgrr, IReturnType[] argumentTypes)
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;
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);
356
return resolver.CreateUnknownMethodResolveResult(invocation);
359
public override object VisitLambdaExpression(LambdaExpression lambdaExpression, object data)
361
return CreateResolveResult(new LambdaReturnType(lambdaExpression, resolver));
364
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
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);
375
ResolveResult targetRR = Resolve(memberReferenceExpression.TargetObject);
376
if (targetRR == null)
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)
390
return CreateTypeResolveResult(resolver.ConstructType(c.DefaultReturnType, memberReferenceExpression.TypeArguments));
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."
403
// MethodGroupResolveResult mgRR = memberRR as MethodGroupResolveResult;
406
// mgRR = targetRR as MethodGroupResolveResult;
408
// if (mgRR != null && !resolver.allowMethodGroupResolveResult)
409
// return CreateMemberResolveResult(mgRR.GetMethodWithEmptyParameterList());
416
IReturnType GetType(ResolveResult targetRR)
418
if (targetRR.ResolvedType != null)
419
return targetRR.ResolvedType;
421
if (targetRR is MixedResolveResult && ((MixedResolveResult)targetRR).TypeResult != null)
422
return ((MixedResolveResult)targetRR).TypeResult.ResolvedType;
427
ResolveResult ResolveMemberInNamespace(string namespaceName, MemberReferenceExpression mre)
430
if (string.IsNullOrEmpty(namespaceName))
431
combinedName = mre.MemberName;
433
combinedName = namespaceName + "." + mre.MemberName;
434
if (resolver.ProjectContent.NamespaceExists(combinedName)) {
435
return new NamespaceResolveResult(resolver.CallingClass, resolver.CallingMember, combinedName);
437
IClass c = resolver.GetClass(combinedName, mre.TypeArguments.Count);
439
return CreateTypeResolveResult(resolver.ConstructType(c.DefaultReturnType, mre.TypeArguments));
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);
450
return resolver.CreateMemberOrMethodGroupResolveResult(
451
null, mre.MemberName, new IList<IMember>[] { possibleMembers }, false, null);
456
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
458
if (objectCreateExpression.IsAnonymousType) {
459
return CreateResolveResult(CreateAnonymousTypeClass(objectCreateExpression.ObjectInitializer).DefaultReturnType);
461
IReturnType rt = TypeVisitor.CreateReturnType(objectCreateExpression.CreateType, resolver);
463
return new UnknownConstructorCallResolveResult(resolver.CallingClass, resolver.CallingMember, objectCreateExpression.CreateType.ToString());
465
return ResolveConstructorOverload(rt, objectCreateExpression.Parameters)
466
?? CreateResolveResult(rt);
470
internal ResolveResult ResolveConstructorOverload(IReturnType rt, List<Expression> arguments)
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);
480
ResolveResult rr = CreateMemberResolveResult(result);
482
rr.ResolvedType = rt;
486
internal ResolveResult ResolveConstructorOverload(IClass c, List<Expression> arguments)
491
return ResolveConstructorOverload(c.DefaultReturnType, arguments);
494
DefaultClass CreateAnonymousTypeClass(CollectionInitializerExpression initializer)
496
List<IReturnType> fieldTypes = new List<IReturnType>();
497
List<string> fieldNames = new List<string>();
499
foreach (Expression expr in initializer.CreateExpressions) {
500
if (expr is MemberInitializerExpression) {
501
// use right part only
502
fieldTypes.Add( ResolveType(((MemberInitializerExpression)expr).Expression) );
504
fieldTypes.Add( ResolveType(expr) );
507
fieldNames.Add(GetAnonymousTypeFieldName(expr));
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);
520
nameBuilder.Append('}');
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);
533
static string GetAnonymousTypeFieldName(Expression expr)
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;
546
public override object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data)
548
return CreateResolveResult(parenthesizedExpression.Expression);
551
public override object VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, object data)
553
ResolveResult targetRR = Resolve(pointerReferenceExpression.TargetObject);
554
if (targetRR == null || targetRR.ResolvedType == null)
556
PointerReturnType type = targetRR.ResolvedType.CastToDecoratingReturnType<PointerReturnType>();
558
return resolver.ResolveMember(type.BaseType, pointerReferenceExpression.MemberName,
559
pointerReferenceExpression.TypeArguments,
560
NRefactoryResolver.IsInvoked(pointerReferenceExpression),
567
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
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);
574
return CreateResolveResult(resolver.ProjectContent.SystemTypes.CreatePrimitive(primitiveExpression.Value.GetType()));
578
public override object VisitQueryExpression(QueryExpression queryExpression, object data)
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"));
587
var selector = new LambdaExpression();
588
selector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
589
selector.ExpressionBody = selectClause.Projection;
590
selector.Parent = fakeInvocation;
592
fakeInvocation.Arguments.Add(selector);
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"));
600
var keySelector = new LambdaExpression();
601
keySelector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
602
keySelector.ExpressionBody = groupClause.GroupBy;
603
keySelector.Parent = fakeInvocation;
605
var elementSelector = new LambdaExpression();
606
elementSelector.Parameters.Add(new ParameterDeclarationExpression(null, "__rangeVariable"));
607
elementSelector.ExpressionBody = groupClause.Projection;
608
elementSelector.Parent = fakeInvocation;
610
fakeInvocation.Arguments.Add(keySelector);
611
fakeInvocation.Arguments.Add(elementSelector);
613
return CreateResolveResult(ResolveType(fakeInvocation));
619
public override object VisitSizeOfExpression(SizeOfExpression sizeOfExpression, object data)
621
return CreateResolveResult(resolver.ProjectContent.SystemTypes.Int32);
624
public override object VisitStackAllocExpression(StackAllocExpression stackAllocExpression, object data)
629
public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
631
if (resolver.CallingClass == null)
633
if (resolver.Language == SupportedLanguage.VBNet && IsInstanceConstructor(resolver.CallingMember)) {
634
return new VBBaseOrThisReferenceInConstructorResolveResult(
635
resolver.CallingClass, resolver.CallingMember, resolver.CallingClass.DefaultReturnType);
637
return CreateResolveResult(resolver.CallingClass.DefaultReturnType);
641
static bool IsInstanceConstructor(IMember member)
643
IMethod m = member as IMethod;
644
return m != null && m.IsConstructor && !m.IsStatic;
647
public override object VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data)
649
return CreateResolveResult(resolver.ProjectContent.SystemTypes.Type);
652
public override object VisitTypeOfIsExpression(TypeOfIsExpression typeOfIsExpression, object data)
654
return CreateResolveResult(resolver.ProjectContent.SystemTypes.Boolean);
657
public override object VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data)
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);
667
string name = resolver.SearchNamespace(reference.Type, typeReferenceExpression.StartLocation);
669
return new NamespaceResolveResult(resolver.CallingClass, resolver.CallingMember, name);
675
return new UnknownIdentifierResolveResult(resolver.CallingClass, resolver.CallingMember, reference.Type);
679
public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)
681
IReturnType type = ResolveType(unaryOperatorExpression.Expression);
684
switch (unaryOperatorExpression.Op) {
685
case UnaryOperatorType.AddressOf:
686
return CreateResolveResult(new PointerReturnType(type));
687
case UnaryOperatorType.Dereference:
688
PointerReturnType prt = type.CastToDecoratingReturnType<PointerReturnType>();
690
return CreateResolveResult(prt.BaseType);
695
return CreateResolveResult(type);
699
public override object VisitUncheckedExpression(UncheckedExpression uncheckedExpression, object data)
701
return CreateResolveResult(uncheckedExpression.Expression);
704
#region XML Literal resolver
705
public override object VisitXmlContentExpression(XmlContentExpression xmlContentExpression, object data)
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"));
719
throw new Exception("Invalid value for XmlContentType");
723
public override object VisitXmlDocumentExpression(XmlDocumentExpression xmlDocumentExpression, object data)
725
return CreateResolveResult(new TypeReference("System.Xml.Linq.XDocument"));
728
public override object VisitXmlElementExpression(XmlElementExpression xmlElementExpression, object data)
730
return CreateResolveResult(new TypeReference("System.Xml.Linq.XElement"));
733
public override object VisitXmlMemberAccessExpression(XmlMemberAccessExpression xmlMemberAccessExpression, object data)
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 }
743
case XmlAxisType.Attribute:
744
return CreateResolveResult(new TypeReference("System.String", true) { IsGlobal = true });
746
throw new Exception("Invalid value for XmlAxisType");