Contains the main resolver logic.
Example #1
0
		public IMethod ResolveConstructor(ITypeResolveContext context)
		{
			CSharpResolver r = new CSharpResolver(context);
			IType type = attributeType.Resolve(context);
			int totalArgumentCount = 0;
			if (positionalArguments != null)
				totalArgumentCount += positionalArguments.Count;
			if (namedCtorArguments != null)
				totalArgumentCount += namedCtorArguments.Count;
			ResolveResult[] arguments = new ResolveResult[totalArgumentCount];
			string[] argumentNames = new string[totalArgumentCount];
			int i = 0;
			if (positionalArguments != null) {
				while (i < positionalArguments.Count) {
					IConstantValue cv = positionalArguments[i];
					arguments[i] = cv.Resolve(context);
					i++;
				}
			}
			if (namedCtorArguments != null) {
				foreach (var pair in namedCtorArguments) {
					argumentNames[i] = pair.Key;
					arguments[i] = pair.Value.Resolve(context);
					i++;
				}
			}
			MemberResolveResult mrr = r.ResolveObjectCreation(type, arguments, argumentNames) as MemberResolveResult;
			return mrr != null ? mrr.Member as IMethod : null;
		}
		public override IEntity ResolveCref(string cref)
		{
			if (cref.Length > 2 && cref[1] == ':') {
				// resolve ID string
				return base.ResolveCref(cref);
			}
			var documentationReference = new CSharpParser().ParseDocumentationReference(cref);
			var csharpContext = context as CSharpTypeResolveContext;
			CSharpResolver resolver;
			if (csharpContext != null) {
				resolver = new CSharpResolver(csharpContext);
			} else {
				resolver = new CSharpResolver(context.Compilation);
			}
			var astResolver = new CSharpAstResolver(resolver, documentationReference);
			var rr = astResolver.Resolve(documentationReference);
			
			MemberResolveResult mrr = rr as MemberResolveResult;
			if (mrr != null)
				return mrr.Member;
			TypeResolveResult trr = rr as TypeResolveResult;
			if (trr != null)
				return trr.Type.GetDefinition();
			return null;
		}
 /// <summary>
 /// Creates a new TypeSystemAstBuilder.
 /// </summary>
 /// <param name="resolver">
 /// A resolver initialized for the position where the type will be inserted.
 /// </param>
 public TypeSystemAstBuilder(CSharpResolver resolver)
 {
     if (resolver == null)
         throw new ArgumentNullException("resolver");
     this.resolver = resolver;
     InitProperties();
 }
		protected string GetShortType (IType type)
		{
			if (builder == null) {
				var ctx = ext.CSharpUnresolvedFile.GetTypeResolveContext (ext.UnresolvedFileCompilation, ext.Document.Editor.Caret.Location) as CSharpTypeResolveContext;
				var state = new CSharpResolver (ctx);
				builder = new TypeSystemAstBuilder (state);
				var dt = state.CurrentTypeDefinition;
				var declaring = ctx.CurrentTypeDefinition != null ? ctx.CurrentTypeDefinition.DeclaringTypeDefinition : null;
				if (declaring != null) {
					while (dt != null) {
						if (dt.Equals (declaring)) {
							builder.AlwaysUseShortTypeNames = true;
							break;
						}
						dt = dt.DeclaringTypeDefinition;
					}
				}
			}
			try {
				return GLib.Markup.EscapeText (builder.ConvertType(type).ToString (ext.FormattingPolicy.CreateOptions ()));
			} catch (Exception e) {
				LoggingService.LogError ("Exception while getting short type.", e);
				return "";
			}
		}
		public CSharpCompletionDataFactory(CSharpCompletionContext completionContext, CSharpResolver contextAtCaret)
		{
			Debug.Assert(completionContext != null);
			Debug.Assert(contextAtCaret != null);
			this.completionContext = completionContext;
			this.contextAtCaret = contextAtCaret;
			this.builder = new TypeSystemAstBuilder(contextAtCaret);
		}
		public override ResolveResult Resolve(CSharpResolver resolver)
		{
			ResolveResult targetRR = target.Resolve(resolver);
			if (targetRR.IsError)
				return targetRR;
			IList<IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);
			return resolver.ResolveMemberAccess(targetRR, identifier, typeArgs, lookupMode);
		}
		public OverrideCompletionData(int declarationBegin, IMember m, CSharpResolver contextAtCaret)
			: base(m)
		{
			this.declarationBegin = declarationBegin;
			this.contextAtCaret = contextAtCaret;
			var ambience = new CSharpAmbience();
			ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames;
			this.CompletionText = ambience.ConvertSymbol(m);
		}
Example #8
0
		public static ResolveResult Resolve(ICompilation compilation, CSharpParsedFile parsedFile, CompilationUnit cu, TextLocation location,
		                                    CancellationToken cancellationToken = default(CancellationToken))
		{
			AstNode node = cu.GetNodeAt(location);
			if (node == null)
				return null;
			AstNode resolvableNode;
			if (node is AstType) {
				resolvableNode = node;
				if (resolvableNode.Parent is ComposedType) {
					while (resolvableNode.Parent is ComposedType)
						resolvableNode = resolvableNode.Parent;
					//node is preffered over the resolvable node. Which shouldn't be done in the case of nullables, arrays etc.
					node = resolvableNode;
				}
			} else if (node is Identifier) {
				resolvableNode = node.Parent;
			} else if (node.NodeType == NodeType.Token) {
				if (node.Parent is ConstructorInitializer) {
					resolvableNode = node.Parent;
				} else {
					return null;
				}
			} else {
				// don't resolve arbitrary nodes - we don't want to show tooltips for everything
				return null;
			}
			
			if (resolvableNode != null && resolvableNode.Parent is ObjectCreateExpression) {
				resolvableNode = resolvableNode.Parent;
			}
			
			InvocationExpression parentInvocation = null;
			if ((resolvableNode is IdentifierExpression || resolvableNode is MemberReferenceExpression || resolvableNode is PointerReferenceExpression)) {
				// we also need to resolve the invocation
				parentInvocation = resolvableNode.Parent as InvocationExpression;
			}
			
			IResolveVisitorNavigator navigator;
			if (parentInvocation != null)
				navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode, parentInvocation });
			else
				navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode });
			
			CSharpResolver resolver = new CSharpResolver(compilation);
			ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator);
			v.Scan(cu);
			
			// Prefer the RR from the token itself, if it was assigned a ResolveResult
			// (this can happen with the identifiers in various nodes such as catch clauses or foreach statements)
			ResolveResult rr = v.GetResolveResult(node) ?? v.GetResolveResult(resolvableNode);
			if (rr is MethodGroupResolveResult && parentInvocation != null)
				return v.GetResolveResult(parentInvocation);
			else
				return rr;
		}
Example #9
0
		/// <summary>
		/// Creates a new C# AST resolver.
		/// </summary>
		/// <param name="resolver">The resolver state at the root node.</param>
		/// <param name="rootNode">The root node of the resolved tree.</param>
		/// <param name="parsedFile">The parsed file for the nodes being resolved. This parameter is used only
		/// when the root node is on the type level; it is not necessary when an expression is passed.
		/// This parameter may be null.</param>
		public CSharpAstResolver(CSharpResolver resolver, AstNode rootNode, CSharpParsedFile parsedFile = null)
		{
			if (resolver == null)
				throw new ArgumentNullException("resolver");
			if (rootNode == null)
				throw new ArgumentNullException("rootNode");
			this.initialResolverState = resolver;
			this.rootNode = rootNode;
			this.parsedFile = parsedFile;
		}
		public EventCreationCompletionData(string handlerName, IType delegateType, IEvent evt, string parameterList, IUnresolvedMember callingMember, IUnresolvedTypeDefinition declaringType, CSharpResolver contextAtCaret)
		{
			if (string.IsNullOrEmpty(handlerName)) {
				handlerName = (evt != null ? evt.Name : "Handle");
			}
			this.handlerName = handlerName;
			this.DisplayText = StringParser.Parse("${res:CSharpBinding.Refactoring.EventCreation.EventHandlerText}", new[] { new StringTagPair("HandlerName", handlerName) });
			this.delegateTypeReference = delegateType.ToTypeReference();
			this.isStatic = callingMember != null && callingMember.IsStatic;
		}
		public EventCreationCompletionData(string handlerName, IType delegateType, IEvent evt, string parameterList, IUnresolvedMember callingMember, IUnresolvedTypeDefinition declaringType, CSharpResolver contextAtCaret)
		{
			if (string.IsNullOrEmpty(handlerName)) {
				handlerName = (evt != null ? evt.Name : "Handle");
			}
			this.handlerName = handlerName;
			this.DisplayText = "<Create " + handlerName + ">";
			this.delegateTypeReference = delegateType.ToTypeReference();
			this.isStatic = callingMember != null && callingMember.IsStatic;
		}
		public SignatureMarkupCreator (CSharpResolver resolver, CSharpFormattingOptions formattingOptions)
		{
			this.colorStyle = SyntaxModeService.GetColorStyle (MonoDevelop.Ide.IdeApp.Preferences.ColorScheme);

			this.resolver = resolver;
			this.astBuilder = new TypeSystemAstBuilder (resolver) {
				ConvertUnboundTypeArguments = true,
				UseAliases = false
			};
			this.formattingOptions = formattingOptions;
		}
		public ResolveResult DoResolve(ITypeResolveContext context)
		{
			CSharpResolver r = new CSharpResolver(context);
			r.CurrentTypeDefinition = parentTypeDefinition;
			r.UsingScope = parentUsingScope;
			IType[] typeArgs = new IType[typeArguments.Count];
			for (int i = 0; i < typeArgs.Length; i++) {
				typeArgs[i] = typeArguments[i].Resolve(context);
			}
			return r.LookupSimpleNameOrTypeName(identifier, typeArgs, lookupMode);
		}
		public ResolveResult DoResolve(ITypeResolveContext context)
		{
			CSharpResolver r = new CSharpResolver(context);
			r.CurrentTypeDefinition = parentTypeDefinition != null ? parentTypeDefinition.GetCompoundClass() : null;
			r.UsingScope = parentUsingScope;
			IType[] typeArgs = new IType[typeArguments.Count];
			for (int i = 0; i < typeArgs.Length; i++) {
				typeArgs[i] = typeArguments[i].Resolve(context);
			}
			return r.LookupSimpleNamespaceOrTypeName(identifier, typeArgs, isInUsingDeclaration);
		}
Example #15
0
		/// <summary>
		/// Creates a new C# AST resolver.
		/// Use this overload if you are resolving within a complete C# file.
		/// </summary>
		/// <param name="compilation">The current compilation.</param>
		/// <param name="syntaxTree">The syntax tree to be resolved.</param>
		/// <param name="unresolvedFile">
		/// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
		/// <para>
		/// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
		/// </para>
		/// <para>
		/// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
		/// member declarations in the AST with members in the type system.
		/// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
		/// member's signature in the AST with the signature in the type system.
		/// </para>
		/// </param>
		public CSharpAstResolver(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile = null)
		{
			if (compilation == null)
				throw new ArgumentNullException("compilation");
			if (syntaxTree == null)
				throw new ArgumentNullException("syntaxTree");
			this.initialResolverState = new CSharpResolver(compilation);
			this.rootNode = syntaxTree;
			this.unresolvedFile = unresolvedFile;
			this.resolveVisitor = new ResolveVisitor(initialResolverState, unresolvedFile);
		}
Example #16
0
		/// <summary>
		/// Creates a new C# AST resolver.
		/// Use this overload if you are resolving within a complete C# file.
		/// </summary>
		/// <param name="compilation">The current compilation.</param>
		/// <param name="compilationUnit">The compilation unit corresponding to the specified parsed file.</param>
		/// <param name="parsedFile">
		/// Optional: Result of the <see cref="TypeSystemConvertVisitor"/> for the file being resolved.
		/// <para>
		/// This is used for setting up the context on the resolver. The parsed file must be registered in the compilation.
		/// </para>
		/// <para>
		/// When a parsedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
		/// member declarations in the AST with members in the type system.
		/// When no parsedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
		/// member's signature in the AST with the signature in the type system.
		/// </para>
		/// </param>
		public CSharpAstResolver(ICompilation compilation, CompilationUnit compilationUnit, CSharpParsedFile parsedFile = null)
		{
			if (compilation == null)
				throw new ArgumentNullException("compilation");
			if (compilationUnit == null)
				throw new ArgumentNullException("compilationUnit");
			this.initialResolverState = new CSharpResolver(compilation);
			this.rootNode = compilationUnit;
			this.parsedFile = parsedFile;
			this.resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile);
		}
		string ConvertHelper(AstNode node, Action<CSharpCodeProvider, CodeObject, TextWriter, CodeGeneratorOptions> action)
		{
			CSharpResolver resolver = new CSharpResolver(compilation);
			resolver = resolver.WithCurrentUsingScope(unresolvedFile.RootUsingScope.Resolve(compilation));
			resolver = resolver.WithCurrentTypeDefinition(compilation.FindType(KnownTypeCode.Object).GetDefinition());
			var codeObj = convertVisitor.Convert(node, new CSharpAstResolver(resolver, node));
			
			StringWriter writer = new StringWriter();
			writer.NewLine = " ";
			action(new CSharpCodeProvider(), codeObj, writer, new CodeGeneratorOptions { IndentString = " " });
			return Regex.Replace(writer.ToString(), @"\s+", " ").Trim();
		}
Example #18
0
 public override ResolveResult Resolve(CSharpResolver resolver)
 {
     ResolveResult[] elements = new ResolveResult[arrayElements.Count];
     for (int i = 0; i < elements.Length; i++) {
         elements[i] = arrayElements[i].Resolve(resolver);
     }
     if (elementType != null) {
         return resolver.ResolveArrayCreation(elementType.Resolve(resolver.CurrentTypeResolveContext), 1, null, elements);
     } else {
         return resolver.ResolveArrayCreation(null, 1, null, elements);
     }
 }
Example #19
0
		string Convert(Expression expr)
		{
			CSharpResolver resolver = new CSharpResolver(compilation);
			resolver = resolver.WithCurrentUsingScope(parsedFile.RootUsingScope.Resolve(compilation));
			resolver = resolver.WithCurrentTypeDefinition(compilation.FindType(KnownTypeCode.Object).GetDefinition());
			var codeExpr = (CodeExpression)convertVisitor.Convert(expr, new CSharpAstResolver(resolver, expr, parsedFile));
			
			StringWriter writer = new StringWriter();
			writer.NewLine = " ";
			new CSharpCodeProvider().GenerateCodeFromExpression(codeExpr, writer, new CodeGeneratorOptions { IndentString = " " });
			return Regex.Replace(writer.ToString(), @"\s+", " ");
		}
		public ImportCompletionData(ITypeDefinition typeDef, CSharpResolver contextAtCaret, bool useFullName)
			: base(typeDef)
		{
			this.Description = "using " + typeDef.Namespace + ";";
			if (useFullName) {
				var astBuilder = new TypeSystemAstBuilder(contextAtCaret);
				insertionText = astBuilder.ConvertType(typeDef).ToString();
			} else {
				insertionText = typeDef.Name;
				insertUsing = typeDef.Namespace;
			}
		}
		public EventCreationCompletionData(string varName, IType delegateType, IEvent evt, string parameterList, IUnresolvedMember callingMember, IUnresolvedTypeDefinition declaringType, CSharpResolver contextAtCaret) : base(evt)
		{
			if (string.IsNullOrEmpty(varName)) {
				this.DisplayText = "Create handler for " + (evt != null ? evt.Name : "");
			}
			else {
				this.DisplayText = "Create handler for " + char.ToUpper(varName[0]) + varName.Substring(1) + (evt != null ? evt.Name : "");
			}
			
			this.DisplayText = "<" + this.DisplayText + ">";
			this.eventDefinition = evt;
			this.delegateType = delegateType;
		}
		public ResolveResult DoResolve(ITypeResolveContext context)
		{
			ResolveResult targetRR = target.DoResolve(context);
			if (targetRR.IsError)
				return targetRR;
			CSharpResolver r = new CSharpResolver(context);
			r.CurrentTypeDefinition = parentTypeDefinition != null ? parentTypeDefinition.GetCompoundClass() : null;
			r.UsingScope = parentUsingScope;
			IType[] typeArgs = new IType[typeArguments.Count];
			for (int i = 0; i < typeArgs.Length; i++) {
				typeArgs[i] = typeArguments[i].Resolve(context);
			}
			return r.ResolveMemberAccess(targetRR, identifier, typeArgs, false);
		}
		public override ResolveResult Resolve(CSharpResolver resolver)
		{
			ResolveResult targetRR = target.Resolve(resolver);
			if (targetRR.IsError)
				return targetRR;
			IList<IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);
			using (var busyLock = BusyManager.Enter(this)) {
				if (busyLock.Success) {
					return resolver.ResolveMemberAccess(targetRR, identifier, typeArgs, lookupMode);
				} else {
					// This can happen for "class Test : $Test.Base$ { public class Base {} }":
					return ErrorResolveResult.UnknownError; // don't cache this error
				}
			}
		}
		public ResolveResult DoResolve(ITypeResolveContext context)
		{
			CacheManager cacheManager = context.CacheManager;
			if (cacheManager != null) {
				ResolveResult cachedResult = cacheManager.GetShared(this) as ResolveResult;
				if (cachedResult != null)
					return cachedResult;
			}
			
			CSharpResolver r = new CSharpResolver(context);
			r.CurrentTypeDefinition = parentTypeDefinition;
			r.CurrentUsingScope = parentUsingScope;
			IType[] typeArgs = new IType[typeArguments.Count];
			for (int i = 0; i < typeArgs.Length; i++) {
				typeArgs[i] = typeArguments[i].Resolve(context);
			}
			ResolveResult rr = r.LookupSimpleNameOrTypeName(identifier, typeArgs, lookupMode);
			if (cacheManager != null)
				cacheManager.SetShared(this, rr);
			return rr;
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="CSharpCompletionContext"/> class.
        /// </summary>
        /// <param name="document">The document, make sure the FileName property is set on the document.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="projectContent">Content of the project.</param>
        /// <param name="usings">The usings.</param>
        public CSharpCompletionContext(IDocument document, int offset, IProjectContent projectContent, string usings = null)
        {
            OriginalDocument = document;
            OriginalOffset = offset;

            //if the document is a c# script we have to soround the document with some code.
            Document = PrepareCompletionDocument(document, ref offset, usings);
            Offset = offset;

            var syntaxTree = new CSharpParser().Parse(Document, Document.FileName);
            syntaxTree.Freeze();
            var unresolvedFile = syntaxTree.ToTypeSystem();

            ProjectContent = projectContent.AddOrUpdateFiles(unresolvedFile);
            //note: it's important that the project content is used that is returned after adding the unresolved file
            Compilation = ProjectContent.CreateCompilation();

            var location = Document.GetLocation(Offset);
            Resolver = unresolvedFile.GetResolver(Compilation, location);
            TypeResolveContextAtCaret = unresolvedFile.GetTypeResolveContext(Compilation, location);
            CompletionContextProvider = new DefaultCompletionContextProvider(Document, unresolvedFile);
        }
Example #26
0
 /// <summary>
 /// Gets the resolver state immediately after the specified node.
 /// That is, if the node is a variable declaration, the returned state will include the newly declared variable.
 /// </summary>
 public CSharpResolver GetResolverStateAfter(AstNode node, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (node == null || node.IsNull)
     {
         throw new ArgumentNullException("node");
     }
     while (node != null && IsUnresolvableNode(node))
     {
         node = node.Parent;
     }
     if (node == null)
     {
         return(initialResolverState);
     }
     InitResolver();
     resolveVisitor.cancellationToken = cancellationToken;
     try {
         CSharpResolver resolver = resolveVisitor.GetResolverStateAfter(node);
         Debug.Assert(resolver != null);
         return(resolver);
     } finally {
         resolveVisitor.cancellationToken = CancellationToken.None;
     }
 }
Example #27
0
        public static ResolveResult Resolve(ITypeResolveContext context, CSharpParsedFile parsedFile, CompilationUnit cu, TextLocation location,
                                            CancellationToken cancellationToken = default(CancellationToken))
        {
            AstNode node = cu.GetNodeAt(location);

            if (node == null)
            {
                return(null);
            }
            AstNode resolvableNode;

            if (node is AstType)
            {
                resolvableNode = node;
                if (resolvableNode.Parent is ComposedType)
                {
                    while (resolvableNode.Parent is ComposedType)
                    {
                        resolvableNode = resolvableNode.Parent;
                    }
                    //node is preffered over the resolvable node. Which shouldn't be done in the case of nullables, arrays etc.
                    node = resolvableNode;
                }
            }
            else if (node is Identifier)
            {
                resolvableNode = node.Parent;
            }
            else if (node.NodeType == NodeType.Token)
            {
                if (node.Parent is ConstructorInitializer)
                {
                    resolvableNode = node.Parent;
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                // don't resolve arbitrary nodes - we don't want to show tooltips for everything
                return(null);
            }

            InvocationExpression parentInvocation = null;

            if ((resolvableNode is IdentifierExpression || resolvableNode is MemberReferenceExpression || resolvableNode is PointerReferenceExpression))
            {
                // we also need to resolve the invocation
                parentInvocation = resolvableNode.Parent as InvocationExpression;
            }

            IResolveVisitorNavigator navigator;

            if (parentInvocation != null)
            {
                navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode, parentInvocation });
            }
            else
            {
                navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode });
            }

            using (var ctx = context.Synchronize()) {
                CSharpResolver resolver = new CSharpResolver(ctx, cancellationToken);
                ResolveVisitor v        = new ResolveVisitor(resolver, parsedFile, navigator);
                v.Scan(cu);

                // Prefer the RR from the token itself, if it was assigned a ResolveResult
                // (this can happen with the identifiers in various nodes such as catch clauses or foreach statements)
                ResolveResult rr = v.GetResolveResult(node) ?? v.GetResolveResult(resolvableNode);
                if (rr is MethodGroupResolveResult && parentInvocation != null)
                {
                    return(v.GetResolveResult(parentInvocation));
                }
                else
                {
                    return(rr);
                }
            }
        }
Example #28
0
 public ObjectInitializerContext(IType type, CSharpResolver.ObjectInitializerContext prev)
 {
     this.type = type;
     this.prev = prev;
 }
Example #29
0
 public virtual object Invoke(CSharpResolver resolver, object lhs, object rhs)
 {
     throw new NotSupportedException();
 }
Example #30
0
		/// <summary>
		/// Creates a new C# AST resolver.
		/// Use this overload if you are resolving code snippets (not necessarily complete files).
		/// </summary>
		/// <param name="resolver">The resolver state at the root node (to be more precise: just outside the root node).</param>
		/// <param name="rootNode">The root node of the tree to be resolved.</param>
		/// <param name="unresolvedFile">
		/// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
		/// <para>
		/// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
		/// </para>
		/// <para>
		/// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
		/// member declarations in the AST with members in the type system.
		/// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
		/// member's signature in the AST with the signature in the type system.
		/// </para>
		/// </param>
		public CSharpAstResolver(CSharpResolver resolver, AstNode rootNode, CSharpUnresolvedFile unresolvedFile = null)
		{
			if (resolver == null)
				throw new ArgumentNullException("resolver");
			if (rootNode == null)
				throw new ArgumentNullException("rootNode");
			this.initialResolverState = resolver;
			this.rootNode = rootNode;
			this.unresolvedFile = unresolvedFile;
			this.resolveVisitor = new ResolveVisitor(initialResolverState, unresolvedFile);
		}
		IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace, out bool isComplete)
		{
			isComplete = false;
			ExpressionResolveResult resolveResult;
			switch (completionChar) {
				// Magic key completion
				case ':':
					var text = GetMemberTextToCaret();
					var lexer = new MiniLexer(text.Item1);
					lexer.Parse();
					if (lexer.IsInSingleComment ||
						lexer.IsInChar ||
						lexer.IsInMultiLineComment ||
						lexer.IsInPreprocessorDirective) {
						return Enumerable.Empty<ICompletionData>();
					}

					if (lexer.IsInString || lexer.IsInVerbatimString)
						return HandleStringFormatItems();
					return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
				case '"':
					text = GetMemberTextToCaret();
					lexer = new MiniLexer(text.Item1);
					lexer.Parse();
					if (lexer.IsInSingleComment ||
						lexer.IsInChar ||
						lexer.IsInMultiLineComment ||
						lexer.IsInPreprocessorDirective) {
						return Enumerable.Empty<ICompletionData>();
					}

					if (lexer.IsInString || lexer.IsInVerbatimString)
						return HandleToStringFormatItems();
					return Enumerable.Empty<ICompletionData>();
				case '.':
					if (IsInsideCommentStringOrDirective()) {
						return Enumerable.Empty<ICompletionData>();
					}
					return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
				case '#':
					if (!IsInPreprocessorDirective())
						return null;
					return GetDirectiveCompletionData();
					// XML doc completion
				case '<':
					if (IsInsideDocComment()) {
						return GetXmlDocumentationCompletionData();
					}
					if (controlSpace) {
						return DefaultControlSpaceItems(ref isComplete);
					}
					return null;
				case '>':
					if (!IsInsideDocComment()) {
						if (offset > 2 && document.GetCharAt(offset - 2) == '-' && !IsInsideCommentStringOrDirective()) {
							return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
						}
						return null;
					}
					return null;

					// Parameter completion
				case '(':
					if (IsInsideCommentStringOrDirective()) {
						return null;
					}
					var invoke = GetInvocationBeforeCursor(true);
					if (invoke == null) {
						if (controlSpace)
							return DefaultControlSpaceItems(ref isComplete, invoke);
						return null;
					}
					if (invoke.Node is TypeOfExpression) {
						return CreateTypeList();
					}
					var invocationResult = ResolveExpression(invoke);
					if (invocationResult == null) {
						return null;
					}
					var methodGroup = invocationResult.Result as MethodGroupResolveResult;
					if (methodGroup != null) {
						return CreateParameterCompletion(
							methodGroup,
							invocationResult.Resolver,
							invoke.Node,
							invoke.Unit,
							0,
							controlSpace
						);
					}

					if (controlSpace) {
						return DefaultControlSpaceItems(ref isComplete, invoke);
					}
					return null;
				case '=':
					return controlSpace ? DefaultControlSpaceItems(ref isComplete) : null;
				case ',':
					int cpos2;
					if (!GetParameterCompletionCommandOffset(out cpos2)) { 
						return null;
					}
					//	completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
					//	int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
					//				return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);	
					break;

					// Completion on space:
				case ' ':
					int tokenIndex = offset;
					string token = GetPreviousToken(ref tokenIndex, false);
					if (IsInsideCommentStringOrDirective()) {
						return null;
					}
					// check propose name, for context <variable name> <ctrl+space> (but only in control space context)
					//IType isAsType = null;
					var isAsExpression = GetExpressionAt(offset);
					if (controlSpace && isAsExpression != null && isAsExpression.Node is VariableDeclarationStatement && token != "new") {
						var parent = isAsExpression.Node as VariableDeclarationStatement;
						var proposeNameList = new CompletionDataWrapper(this);
						if (parent.Variables.Count != 1)
							return DefaultControlSpaceItems(ref isComplete, isAsExpression, controlSpace);

						foreach (var possibleName in GenerateNameProposals (parent.Type)) {
							if (possibleName.Length > 0) {
								proposeNameList.Result.Add(factory.CreateLiteralCompletionData(possibleName.ToString()));
							}
						}

						AutoSelect = false;
						AutoCompleteEmptyMatch = false;
						isComplete = true;
						return proposeNameList.Result;
					}
					//				int tokenIndex = offset;
					//				string token = GetPreviousToken (ref tokenIndex, false);
					//				if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
					//					resolver = CreateResolver ();
					//					ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType);
					//					IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
					//					if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
					//						return CreateCtrlSpaceCompletionData (completionContext, result); 
					//				}
					if (token == "=") {
						int j = tokenIndex;
						string prevToken = GetPreviousToken(ref j, false);
						if (prevToken == "=" || prevToken == "+" || prevToken == "-" || prevToken == "!") {
							token = prevToken + token;
							tokenIndex = j;
						}
					}
					switch (token) {
						case "(":
						case ",":
							int cpos;
							if (!GetParameterCompletionCommandOffset(out cpos)) { 
								break;
							}
							int currentParameter = GetCurrentParameterIndex(cpos - 1, this.offset) - 1;
							if (currentParameter < 0) {
								return null;
							}
							invoke = GetInvocationBeforeCursor(token == "(");
							if (invoke == null) {
								return null;
							}
							invocationResult = ResolveExpression(invoke);
							if (invocationResult == null) {
								return null;
							}
							methodGroup = invocationResult.Result as MethodGroupResolveResult;
							if (methodGroup != null) {
								return CreateParameterCompletion(
									methodGroup,
									invocationResult.Resolver,
									invoke.Node,
									invoke.Unit,
									currentParameter,
									controlSpace);
							}
							return null;
						case "=":
						case "==":
						case "!=":
							GetPreviousToken(ref tokenIndex, false);
							var expressionOrVariableDeclaration = GetExpressionAt(tokenIndex);
							if (expressionOrVariableDeclaration == null) {
								return null;
							}
							resolveResult = ResolveExpression(expressionOrVariableDeclaration);
							if (resolveResult == null) {
								return null;
							}
							if (resolveResult.Result.Type.Kind == TypeKind.Enum) {
								var wrapper = new CompletionDataWrapper(this);
								AddContextCompletion(
									wrapper,
									resolveResult.Resolver,
									expressionOrVariableDeclaration.Node);
								AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver);
								AutoCompleteEmptyMatch = false;
								return wrapper.Result;
							}
							//				
							//					if (resolvedType.FullName == DomReturnType.Bool.FullName) {
							//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
							//						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
							//						completionList.AutoCompleteEmptyMatch = false;
							//						cdc.Add ("true", "md-keyword");
							//						cdc.Add ("false", "md-keyword");
							//						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
							//						return completionList;
							//					}
							//					if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
							//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
							//						string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
							//						string varName = GetPreviousMemberReferenceExpression (tokenIndex);
							//						completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
							//						
							//						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
							//						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
							//						foreach (var data in completionList) {
							//							if (data is MemberCompletionData) 
							//								((MemberCompletionData)data).IsDelegateExpected = true;
							//						}
							//						return completionList;
							//					}
							return null;
						case "+=":
						case "-=":
							GetPreviousToken(ref tokenIndex, false);

							expressionOrVariableDeclaration = GetExpressionAt(tokenIndex);
							if (expressionOrVariableDeclaration == null) {
								return null;
							}

							resolveResult = ResolveExpression(expressionOrVariableDeclaration);
							if (resolveResult == null) {
								return null;
							}


							var mrr = resolveResult.Result as MemberResolveResult;
							if (mrr != null) {
								var evt = mrr.Member as IEvent;
								if (evt == null) {
									return null;
								}
								var delegateType = evt.ReturnType;
								if (delegateType.Kind != TypeKind.Delegate) {
									return null;
								}

								var wrapper = new CompletionDataWrapper(this);
								if (currentType != null) {
									//							bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
									foreach (var method in ctx.CurrentTypeDefinition.Methods) {
										if (MatchDelegate(delegateType, method) /*										&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) {
											wrapper.AddMember(method);
											//									data.SetText (data.CompletionText + ";");
										}
									}
								}
								if (token == "+=") {
									string parameterDefinition = AddDelegateHandlers(
										wrapper,
										delegateType
									);
									string varName = GetPreviousMemberReferenceExpression(tokenIndex);
									wrapper.Result.Add(
										factory.CreateEventCreationCompletionData(
											varName,
											delegateType,
											evt,
											parameterDefinition,
											currentMember,
											currentType)
									);
								}

								return wrapper.Result;
							}
							return null;
						case ":":
							if (currentMember == null) {
								token = GetPreviousToken(ref tokenIndex, false);
								token = GetPreviousToken(ref tokenIndex, false);
								if (token == "enum")
									return HandleEnumContext();
								var wrapper = new CompletionDataWrapper(this);
								AddTypesAndNamespaces(
									wrapper,
									GetState(),
									null,
									t =>  {
										if (currentType != null && currentType.ReflectionName.Equals(t.ReflectionName))
											return null;
										var def = t.GetDefinition();
										if (def != null && t.Kind != TypeKind.Interface && (def.IsSealed ||def.IsStatic))
											return null;
										return t;
									}
								);
								return wrapper.Result;
							}
							return null;
					}

					var keywordCompletion = HandleKeywordCompletion(tokenIndex, token);
					if (keywordCompletion == null && controlSpace) {
						goto default;
					}
					return keywordCompletion;
					// Automatic completion
				default:
					if (IsInsideCommentStringOrDirective()) {
						tokenIndex = offset;
						token = GetPreviousToken(ref tokenIndex, false);
						if (IsInPreprocessorDirective() && (token.Length == 1 && char.IsLetter(completionChar) || controlSpace)) {
							while (token != null && document.GetCharAt(tokenIndex - 1) != '#') {
								token = GetPreviousToken(ref tokenIndex, false);
							}
							if (token != null)
								return HandleKeywordCompletion(tokenIndex, token);
						}
						return null;
					}
					char prevCh = offset > 2 ? document.GetCharAt(offset - 2) : ';';
					char nextCh = offset < document.TextLength ? document.GetCharAt(offset) : ' ';
					const string allowedChars = ";,.[](){}+-*/%^?:&|~!<>=";

					if ((!Char.IsWhiteSpace(nextCh) && allowedChars.IndexOf(nextCh) < 0) || !(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) {
						if (!controlSpace)
							return null;
					}

					if (IsInLinqContext(offset)) {
						if (!controlSpace && !(char.IsLetter(completionChar) || completionChar == '_')) {
							return null;
						}
						tokenIndex = offset;
						token = GetPreviousToken(ref tokenIndex, false);
						// token last typed
						if (!char.IsWhiteSpace(completionChar) && !linqKeywords.Contains(token)) {
							token = GetPreviousToken(ref tokenIndex, false);
						}
						// token last typed

						if (linqKeywords.Contains(token)) {
							if (token == "from") {
								// after from no auto code completion.
								return null;
							}
							return DefaultControlSpaceItems(ref isComplete);
						}
						var dataList = new CompletionDataWrapper(this);
						AddKeywords(dataList, linqKeywords);
						return dataList.Result;
					}
					if (currentType != null && currentType.Kind == TypeKind.Enum) {
						if (!char.IsLetter(completionChar))
							return null;
						return HandleEnumContext();
					}
					var contextList = new CompletionDataWrapper(this);
					var identifierStart = GetExpressionAtCursor();
					if (!(char.IsLetter(completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null)) {
						return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
					}

					if (identifierStart != null) {
						if (identifierStart.Node is TypeParameterDeclaration) {
							return null;
						}

						if (identifierStart.Node is MemberReferenceExpression) {
							return HandleMemberReferenceCompletion(
								new ExpressionResult(
									((MemberReferenceExpression)identifierStart.Node).Target,
									identifierStart.Unit
								)
							);
						}

						if (identifierStart.Node is Identifier) {
							if (identifierStart.Node.Parent is GotoStatement)
								return null;

							// May happen in variable names
							return controlSpace ? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
						}
						if (identifierStart.Node is VariableInitializer && location <= ((VariableInitializer)identifierStart.Node).NameToken.EndLocation) {
							return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
						}
						if (identifierStart.Node is CatchClause) {
							if (((CatchClause)identifierStart.Node).VariableNameToken.IsInside(location)) {
								return null;
							}
						}
						if (identifierStart.Node is AstType && identifierStart.Node.Parent is CatchClause) {
							return HandleCatchClauseType(identifierStart);
						}

						var pDecl = identifierStart.Node as ParameterDeclaration;
						if (pDecl != null && pDecl.Parent is LambdaExpression) {
							return null;
						}
					}


					// Do not pop up completion on identifier identifier (should be handled by keyword completion).
					tokenIndex = offset - 1;
					token = GetPreviousToken(ref tokenIndex, false);
					if (token == "class" || token == "interface" || token == "struct" || token == "enum" || token == "namespace") {
						// after these always follows a name
						return null;
					}
					var keywordresult = HandleKeywordCompletion(tokenIndex, token);
					if (keywordresult != null) {
						return keywordresult;
					}

					if ((!Char.IsWhiteSpace(nextCh) && allowedChars.IndexOf(nextCh) < 0) || !(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) {
						if (controlSpace)
							return DefaultControlSpaceItems(ref isComplete, identifierStart);
					}

					int prevTokenIndex = tokenIndex;
					var prevToken2 = GetPreviousToken(ref prevTokenIndex, false);
					if (prevToken2 == "delegate") {
						// after these always follows a name
						return null;
					}

					if (identifierStart == null && !string.IsNullOrEmpty(token) && !IsInsideCommentStringOrDirective() && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
						char last = token [token.Length - 1];
						if (char.IsLetterOrDigit(last) || last == '_' || token == ">") {
							return HandleKeywordCompletion(tokenIndex, token);
						}
					}
					if (identifierStart == null) {
						var accCtx = HandleAccessorContext();
						if (accCtx != null) {
							return accCtx;
						}
						return DefaultControlSpaceItems(ref isComplete, null, controlSpace);
					}
					CSharpResolver csResolver;
					AstNode n = identifierStart.Node;
					if (n.Parent is NamedArgumentExpression)
						n = n.Parent;

					if (n != null && n.Parent is AnonymousTypeCreateExpression) {
						AutoSelect = false;
					}

					// new { b$ } 
					if (n is IdentifierExpression && n.Parent is AnonymousTypeCreateExpression)
						return null;

					// Handle foreach (type name _
					if (n is IdentifierExpression) {
						var prev = n.GetPrevNode() as ForeachStatement;
						while (prev != null && prev.EmbeddedStatement is ForeachStatement)
							prev = (ForeachStatement)prev.EmbeddedStatement;
						if (prev != null && prev.InExpression.IsNull) {
							if (IncludeKeywordsInCompletionList)
								contextList.AddCustom("in");
							return contextList.Result;
						}
					}
					// Handle object/enumerable initialzer expressions: "new O () { P$"
					if (n is IdentifierExpression && n.Parent is ArrayInitializerExpression && !(n.Parent.Parent is ArrayCreateExpression)) {
						var result = HandleObjectInitializer(identifierStart.Unit, n);
						if (result != null)
							return result;
					}

					if (n != null && n.Parent is InvocationExpression ||
						n.Parent is ParenthesizedExpression && n.Parent.Parent is InvocationExpression) {
						if (n.Parent is ParenthesizedExpression)
							n = n.Parent;
						var invokeParent = (InvocationExpression)n.Parent;
						var invokeResult = ResolveExpression(
							invokeParent.Target
						);
						var mgr = invokeResult != null ? invokeResult.Result as MethodGroupResolveResult : null;
						if (mgr != null) {
							int idx = 0;
							foreach (var arg in invokeParent.Arguments) {
								if (arg == n) {
									break;
								}
								idx++;
							}

							foreach (var method in mgr.Methods) {
								if (idx < method.Parameters.Count && method.Parameters [idx].Type.Kind == TypeKind.Delegate) {
									AutoSelect = false;
									AutoCompleteEmptyMatch = false;
								}
								foreach (var p in method.Parameters) {
									contextList.AddNamedParameterVariable(p);
								}
							}
							idx++;
							foreach (var list in mgr.GetEligibleExtensionMethods (true)) {
								foreach (var method in list) {
									if (idx < method.Parameters.Count && method.Parameters [idx].Type.Kind == TypeKind.Delegate) {
										AutoSelect = false;
										AutoCompleteEmptyMatch = false;
									}
								}
							}
						}
					}

					if (n != null && n.Parent is ObjectCreateExpression) {
						var invokeResult = ResolveExpression(n.Parent);
						var mgr = invokeResult != null ? invokeResult.Result as ResolveResult : null;
						if (mgr != null) {
							foreach (var constructor in mgr.Type.GetConstructors ()) {
								foreach (var p in constructor.Parameters) {
									contextList.AddVariable(p);
								}
							}
						}
					}

					if (n is IdentifierExpression) {
						var bop = n.Parent as BinaryOperatorExpression;
						Expression evaluationExpr = null;

						if (bop != null && bop.Right == n && (bop.Operator == BinaryOperatorType.Equality || bop.Operator == BinaryOperatorType.InEquality)) {
							evaluationExpr = bop.Left;
						}
						// check for compare to enum case 
						if (evaluationExpr != null) {
							resolveResult = ResolveExpression(evaluationExpr);
							if (resolveResult != null && resolveResult.Result.Type.Kind == TypeKind.Enum) {
								var wrapper = new CompletionDataWrapper(this);
								AddContextCompletion(
									wrapper,
									resolveResult.Resolver,
									evaluationExpr
								);
								AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver);
								AutoCompleteEmptyMatch = false;
								return wrapper.Result;
							}
						}
					}

					if (n is Identifier && n.Parent is ForeachStatement) {
						if (controlSpace) {
							return DefaultControlSpaceItems(ref isComplete);
						}
						return null;
					}

					if (n is ArrayInitializerExpression) {
						// check for new [] {...} expression -> no need to resolve the type there
						var parent = n.Parent as ArrayCreateExpression;
						if (parent != null && parent.Type.IsNull) {
							return DefaultControlSpaceItems(ref isComplete);
						}

						var initalizerResult = ResolveExpression(n.Parent);

						var concreteNode = identifierStart.Unit.GetNodeAt<IdentifierExpression>(location);
						// check if we're on the right side of an initializer expression
						if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) {
							return DefaultControlSpaceItems(ref isComplete);
						}
						if (initalizerResult != null && initalizerResult.Result.Type.Kind != TypeKind.Unknown) { 

							foreach (var property in initalizerResult.Result.Type.GetProperties ()) {
								if (!property.IsPublic) {
									continue;
								}
								var data = contextList.AddMember(property);
								if (data != null)
									data.DisplayFlags |= DisplayFlags.NamedArgument;
							}
							foreach (var field in initalizerResult.Result.Type.GetFields ()) {       
								if (!field.IsPublic) {
									continue;
								}
								var data = contextList.AddMember(field);
								if (data != null)
									data.DisplayFlags |= DisplayFlags.NamedArgument;
							}
							return contextList.Result;
						}
						return DefaultControlSpaceItems(ref isComplete);
					}

					if (IsAttributeContext(n)) {
						// add attribute targets
						if (currentType == null) {
							contextList.AddCustom("assembly");
							contextList.AddCustom("module");
							contextList.AddCustom("type");
						} else {
							contextList.AddCustom("param");
							contextList.AddCustom("field");
							contextList.AddCustom("property");
							contextList.AddCustom("method");
							contextList.AddCustom("event");
						}
						contextList.AddCustom("return");
					}
					if (n is MemberType) {
						resolveResult = ResolveExpression(
							((MemberType)n).Target
						);
						return CreateTypeAndNamespaceCompletionData(
							location,
							resolveResult.Result,
							((MemberType)n).Target,
							resolveResult.Resolver
						);
					}
					if (n != null/*					 && !(identifierStart.Item2 is TypeDeclaration)*/) {
						csResolver = new CSharpResolver(ctx);
						var nodes = new List<AstNode>();
						nodes.Add(n);
						if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
							nodes.Add(n.Parent);
						}
						var astResolver = CompletionContextProvider.GetResolver(csResolver, identifierStart.Unit);
						astResolver.ApplyNavigator(new NodeListResolveVisitorNavigator(nodes));
						try {
							csResolver = astResolver.GetResolverStateBefore(n);
						} catch (Exception) {
							csResolver = GetState();
						}
						// add attribute properties.
						if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
							var rr = ResolveExpression(n.Parent);
							if (rr != null)
								AddAttributeProperties(contextList, rr.Result);
						}
					} else {
						csResolver = GetState();
					}
					// identifier has already started with the first letter
					offset--;
					AddContextCompletion(
						contextList,
						csResolver,
						identifierStart.Node
					);
					return contextList.Result;
					//				if (stub.Parent is BlockStatement)

					//				result = FindExpression (dom, completionContext, -1);
					//				if (result == null)
					//					return null;
					//				 else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
					//					triggerWordLength = 1;
					//					bool autoSelect = true;
					//					IType returnType = null;
					//					if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
					//						ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
					//						NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
					//						if (dataProvider != null) {
					//							int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
					//							foreach (var method in dataProvider.Methods) {
					//								if (i < method.Parameters.Count) {
					//									returnType = dom.GetType (method.Parameters [i].ReturnType);
					//									autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
					//									break;
					//								}
					//							}
					//						}
					//					}
					//					// Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
					//					//if (result.ExpressionContext == ExpressionContext.TypeName)
					//					//	autoSelect = false;
					//					CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
					//					AddEnumMembers (dataList, returnType);
					//					dataList.AutoSelect = autoSelect;
					//					return dataList;
					//				} else {
					//					result = FindExpression (dom, completionContext, 0);
					//					tokenIndex = offset;
					//					
					//					// check foreach case, unfortunately the expression finder is too dumb to handle full type names
					//					// should be overworked if the expression finder is replaced with a mcs ast based analyzer.
					//					var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
					//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
					//				
					//					// read return types to '(' token
					//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
					//					if (possibleForeachToken == ">") {
					//						while (possibleForeachToken != null && possibleForeachToken != "(") {
					//							possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
					//						}
					//					} else {
					//						possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
					//						if (possibleForeachToken == ".")
					//							while (possibleForeachToken != null && possibleForeachToken != "(")
					//								possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
					//					}
					//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
					//				
					//					if (possibleForeachToken == "foreach") {
					//						result.ExpressionContext = ExpressionContext.ForeachInToken;
					//					} else {
					//						return null;
					//						//								result.ExpressionContext = ExpressionContext.IdentifierExpected;
					//					}
					//					result.Expression = "";
					//					result.Region = DomRegion.Empty;
					//				
					//					return CreateCtrlSpaceCompletionData (completionContext, result);
					//				}
					//				break;
			}
			return null;

		}
		public OverrideToStringCompletionData(int declarationBegin, IMember m, CSharpResolver contextAtCaret)
			: base(declarationBegin, m, contextAtCaret)
		{
		}
		IEnumerable<ICompletionData> CreateCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state, Func<IType, IType> typePred = null)
		{
			if (resolveResult == null /*			|| resolveResult.IsError*/) {
				return null;
			}

			var lookup = new MemberLookup(
				ctx.CurrentTypeDefinition,
				Compilation.MainAssembly
			);

			if (resolveResult is NamespaceResolveResult) {
				var nr = (NamespaceResolveResult)resolveResult;
				var namespaceContents = new CompletionDataWrapper(this);

				foreach (var cl in nr.Namespace.Types) {
					if (!lookup.IsAccessible(cl, false))
						continue;
					IType addType = typePred != null ? typePred(cl) : cl;
					if (addType != null)
						namespaceContents.AddType(addType, false);
				}

				foreach (var ns in nr.Namespace.ChildNamespaces) {
					namespaceContents.AddNamespace(lookup, ns);
				}
				return namespaceContents.Result;
			}
			IType type = resolveResult.Type;

			if (type.Namespace == "System" && type.Name == "Void")
				return null;

			if (resolvedNode.Parent is PointerReferenceExpression && (type is PointerType)) {
				resolveResult = new OperatorResolveResult(((PointerType)type).ElementType, System.Linq.Expressions.ExpressionType.Extension, resolveResult);
			}

			//var typeDef = resolveResult.Type.GetDefinition();
			var result = new CompletionDataWrapper(this);
			bool includeStaticMembers = false;

			if (resolveResult is LocalResolveResult) {
				if (resolvedNode is IdentifierExpression) {
					var mrr = (LocalResolveResult)resolveResult;
					includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
				}
			}
			if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
				foreach (var field in type.GetFields ()) {
					if (!lookup.IsAccessible(field, false))
						continue;
					result.AddMember(field);
				}
				return result.Result;
			}

			bool isProtectedAllowed = resolveResult is ThisResolveResult ? true : lookup.IsProtectedAccessAllowed(type);
			bool skipNonStaticMembers = (resolveResult is TypeResolveResult);

			if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
				var mrr = (MemberResolveResult)resolveResult;
				includeStaticMembers = mrr.Member.Name == mrr.Type.Name;

				TypeResolveResult trr;
				if (state.IsVariableReferenceWithSameType(
					resolveResult,
					((IdentifierExpression)resolvedNode).Identifier,
					out trr
				)) {
					if (currentMember != null && mrr.Member.IsStatic ^ currentMember.IsStatic) {
						skipNonStaticMembers = true;

						if (trr.Type.Kind == TypeKind.Enum) {
							foreach (var field in trr.Type.GetFields ()) {
								if (lookup.IsAccessible(field, false))
									result.AddMember(field);
							}
							return result.Result;
						}
					}
				}
				// ADD Aliases
				var scope = ctx.CurrentUsingScope;

				for (var n = scope; n != null; n = n.Parent) {
					foreach (var pair in n.UsingAliases) {
						if (pair.Key == mrr.Member.Name) {
							foreach (var r in CreateCompletionData (location, pair.Value, resolvedNode, state)) {
								if (r is IEntityCompletionData && ((IEntityCompletionData)r).Entity is IMember) {
									result.AddMember((IMember)((IEntityCompletionData)r).Entity);
								} else {
									result.Add(r);
								}
							}
						}
					}
				}				


			}
			if (resolveResult is TypeResolveResult && (resolvedNode is IdentifierExpression || resolvedNode is MemberReferenceExpression)) {
				includeStaticMembers = true;
			}

			//			Console.WriteLine ("type:" + type +"/"+type.GetType ());
			//			Console.WriteLine ("current:" + ctx.CurrentTypeDefinition);
			//			Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed + " static: "+ includeStaticMembers);
			//			Console.WriteLine (resolveResult);
			//			Console.WriteLine ("node:" + resolvedNode);
			//			Console.WriteLine (currentMember !=  null ? currentMember.IsStatic : "currentMember == null");

			if (resolvedNode.Annotation<ObjectCreateExpression>() == null) {
				//tags the created expression as part of an object create expression.
				/*				
				var filteredList = new List<IMember>();
				foreach (var member in type.GetMembers ()) {
					filteredList.Add(member);
				}
				
				foreach (var member in filteredList) {
					//					Console.WriteLine ("add:" + member + "/" + member.IsStatic);
					result.AddMember(member);
				}*/
				foreach (var member in lookup.GetAccessibleMembers (resolveResult)) {
					if (member.SymbolKind == SymbolKind.Indexer || member.SymbolKind == SymbolKind.Operator || member.SymbolKind == SymbolKind.Constructor || member.SymbolKind == SymbolKind.Destructor) {
						continue;
					}
					if (resolvedNode is BaseReferenceExpression && member.IsAbstract) {
						continue;
					}
					if (member is IType) {
						if (resolveResult is TypeResolveResult || includeStaticMembers) {
							if (!lookup.IsAccessible(member, isProtectedAllowed))
								continue;
							result.AddType((IType)member, false);
							continue;
						}
					}
					bool memberIsStatic = member.IsStatic;
					if (!includeStaticMembers && memberIsStatic && !(resolveResult is TypeResolveResult)) {
						//						Console.WriteLine ("skip static member: " + member.FullName);
						continue;
					}

					var field = member as IField;
					if (field != null) {
						memberIsStatic |= field.IsConst;
					}
					if (!memberIsStatic && skipNonStaticMembers) {
						continue;
					}

					if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
						continue;
					}
					if (member.SymbolKind == SymbolKind.Operator) {
						continue;
					}

					if (member is IMember) {
						result.AddMember((IMember)member);
					}
				}
			}

			if (!(resolveResult is TypeResolveResult || includeStaticMembers)) {
				foreach (var meths in state.GetExtensionMethods (type)) {
					foreach (var m in meths) {
						if (!lookup.IsAccessible(m, isProtectedAllowed))
							continue;
						result.AddMember(new ReducedExtensionMethod(m));
					}
				}
			}

			//			IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
			//			CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
			//			col.HideExtensionParameter = !resolveResult.StaticResolve;
			//			col.NamePrefix = expressionResult.Expression;
			//			bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
			//			if (objects != null) {
			//				foreach (object obj in objects) {
			//					if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
			//						continue;
			//					if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
			//						continue;
			//					if (showOnlyTypes && !(obj is IType))
			//						continue;
			//					CompletionData data = col.Add (obj);
			//					if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
			//						string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
			//						data.SetText (newText);
			//					}
			//				}
			//			}

			return result.Result;
		}
Example #34
0
 public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
 {
     return(string.Concat(lhs, rhs));
 }
Example #35
0
 public override void SetUp()
 {
     base.SetUp();
     resolver = new CSharpResolver(compilation);
 }
Example #36
0
 public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
 {
     return(baseMethod.Invoke(resolver, lhs, rhs));
 }
Example #37
0
 public override void SetUp()
 {
     base.SetUp();
     resolver = new CSharpResolver(compilation).WithCurrentUsingScope(MakeUsingScope(string.Empty));
 }