internal static IEnumerable<IType> GetValidTypes(CSharpAstResolver resolver, AstNode expr) { if (expr.Parent is DirectionExpression) { var parent = expr.Parent.Parent; if (parent is InvocationExpression) { var invoke = (InvocationExpression)parent; return GetAllValidTypesFromInvokation(resolver, invoke, expr.Parent); } } if (expr.Parent is ArrayInitializerExpression) { if (expr is NamedExpression) return new [] { resolver.Resolve(((NamedExpression)expr).Expression).Type }; var aex = expr.Parent as ArrayInitializerExpression; if (aex.IsSingleElement) aex = aex.Parent as ArrayInitializerExpression; var type = GetElementType(resolver, resolver.Resolve(aex.Parent).Type); if (type.Kind != TypeKind.Unknown) return new [] { type }; } if (expr.Parent is ObjectCreateExpression) { var invoke = (ObjectCreateExpression)expr.Parent; return GetAllValidTypesFromObjectCreation(resolver, invoke, expr); } if (expr.Parent is ArrayCreateExpression) { var ace = (ArrayCreateExpression)expr.Parent; if (!ace.Type.IsNull) { return new [] { resolver.Resolve(ace.Type).Type }; } } if (expr.Parent is InvocationExpression) { var parent = expr.Parent; if (parent is InvocationExpression) { var invoke = (InvocationExpression)parent; return GetAllValidTypesFromInvokation(resolver, invoke, expr); } } if (expr.Parent is VariableInitializer) { var initializer = (VariableInitializer)expr.Parent; var field = initializer.GetParent<FieldDeclaration>(); if (field != null) return new [] { resolver.Resolve(field.ReturnType).Type }; return new [] { resolver.Resolve(initializer).Type }; } if (expr.Parent is CastExpression) { var cast = (CastExpression)expr.Parent; return new [] { resolver.Resolve(cast.Type).Type }; } if (expr.Parent is AsExpression) { var cast = (AsExpression)expr.Parent; return new [] { resolver.Resolve(cast.Type).Type }; } if (expr.Parent is AssignmentExpression) { var assign = (AssignmentExpression)expr.Parent; var other = assign.Left == expr ? assign.Right : assign.Left; return new [] { resolver.Resolve(other).Type }; } if (expr.Parent is BinaryOperatorExpression) { var assign = (BinaryOperatorExpression)expr.Parent; var other = assign.Left == expr ? assign.Right : assign.Left; return new [] { resolver.Resolve(other).Type }; } if (expr.Parent is ReturnStatement) { var state = resolver.GetResolverStateBefore(expr.Parent); if (state != null && state.CurrentMember != null) return new [] { state.CurrentMember.ReturnType }; } if (expr.Parent is YieldReturnStatement) { var state = resolver.GetResolverStateBefore(expr); if (state != null && (state.CurrentMember.ReturnType is ParameterizedType)) { var pt = (ParameterizedType)state.CurrentMember.ReturnType; if (pt.FullName == "System.Collections.Generic.IEnumerable") { return new [] { pt.TypeArguments.First() }; } } } if (expr.Parent is UnaryOperatorExpression) { var uop = (UnaryOperatorExpression)expr.Parent; switch (uop.Operator) { case UnaryOperatorType.Not: return new [] { resolver.Compilation.FindType(KnownTypeCode.Boolean) }; case UnaryOperatorType.Minus: case UnaryOperatorType.Plus: case UnaryOperatorType.Increment: case UnaryOperatorType.Decrement: case UnaryOperatorType.PostIncrement: case UnaryOperatorType.PostDecrement: return new [] { resolver.Compilation.FindType(KnownTypeCode.Int32) }; } } return Enumerable.Empty<IType>(); }
public ResolveResult GetLanguageItem (MonoDevelop.Ide.Gui.Document doc, int offset, string expression) { if (offset < 0) { return null; } var parsedDocument = doc.ParsedDocument; if (parsedDocument == null) return null; var data = doc.Editor; var loc = data.OffsetToLocation (offset); var unit = parsedDocument.GetAst<SyntaxTree> (); var parsedFile = parsedDocument.ParsedFile as CSharpUnresolvedFile; if (unit == null || parsedFile == null) { return null; } var node = unit.GetNodeAt (loc); if (node == null) { return null; } var resolver = new CSharpAstResolver (doc.Compilation, unit, parsedFile); resolver.ApplyNavigator (new NodeListResolveVisitorNavigator (node), CancellationToken.None); var state = resolver.GetResolverStateBefore (node, CancellationToken.None); return state.LookupSimpleNameOrTypeName (expression, new List<IType> (), NameLookupMode.Expression); }