protected override int GetAdjustedContextPoint(int contextPoint, Document document)
        {
            // Determine the position in the buffer at which to end the tracking span representing
            // the part of the imagininary buffer before the text in the view. 
            var tree = document.GetCSharpSyntaxTreeAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None);
            var token = tree.FindTokenOnLeftOfPosition(contextPoint, CancellationToken.None);

            // Special case to handle class designer because it asks for debugger IntelliSense using
            // spans between members.
            if (contextPoint > token.Span.End &&
                token.IsKindOrHasMatchingText(SyntaxKind.CloseBraceToken) &&
                token.Parent.IsKind(SyntaxKind.Block) &&
                token.Parent.Parent is MemberDeclarationSyntax)
            {
                return contextPoint;
            }

            if (token.IsKindOrHasMatchingText(SyntaxKind.CloseBraceToken) &&
                token.Parent.IsKind(SyntaxKind.Block))
            {
                return token.SpanStart;
            }

            return token.FullSpan.End;
        }
        internal static async Task<DebugLocationInfo> GetInfoAsync(Document document, int position, CancellationToken cancellationToken)
        {
            string name = null;
            int lineOffset = 0;

            // Note that we get the current partial solution here.  Technically, this means that we may
            // not fully understand the signature of the member.  But that's ok.  We just need this
            // symbol so we can create a display string to put into the debugger.  If we try to
            // find the document in the "CurrentSolution" then when we try to get the semantic 
            // model below then it might take a *long* time as all dependent compilations are built.
            var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(position);
            SyntaxNode memberDecl = token.GetAncestor<MemberDeclarationSyntax>();

            // field or event field declarations may contain multiple variable declarators. Try finding the correct one.
            // If the position does not point to one, try using the first one.
            if (memberDecl != null &&
                (memberDecl.Kind() == SyntaxKind.FieldDeclaration || memberDecl.Kind() == SyntaxKind.EventFieldDeclaration))
            {
                SeparatedSyntaxList<VariableDeclaratorSyntax> variableDeclarators = ((BaseFieldDeclarationSyntax)memberDecl).Declaration.Variables;

                foreach (var declarator in variableDeclarators)
                {
                    if (declarator.FullSpan.Contains(token.FullSpan))
                    {
                        memberDecl = declarator;
                        break;
                    }
                }

                if (memberDecl == null)
                {
                    memberDecl = variableDeclarators.Count > 0 ? variableDeclarators[0] : null;
                }
            }

            if (memberDecl != null)
            {
                var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                var memberSymbol = semanticModel.GetDeclaredSymbol(memberDecl, cancellationToken);

                if (memberSymbol != null)
                {
                    var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
                    var lineNumber = text.Lines.GetLineFromPosition(position).LineNumber;

                    var accessor = token.GetAncestor<AccessorDeclarationSyntax>();
                    var memberLine = accessor == null
                        ? text.Lines.GetLineFromPosition(memberDecl.SpanStart).LineNumber
                        : text.Lines.GetLineFromPosition(accessor.SpanStart).LineNumber;

                    name = memberSymbol.ToDisplayString(s_nameFormat);
                    lineOffset = lineNumber - memberLine;
                    return new DebugLocationInfo(name, lineOffset);
                }
            }

            return default(DebugLocationInfo);
        }
 public async Task<IList<string>> GetProximityExpressionsAsync(
     Document document,
     int position,
     CancellationToken cancellationToken)
 {
     var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
     return Do(tree, position, cancellationToken);
 }
        protected override async Task<bool> IsExclusiveAsync(Document document, int caretPosition, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            var token = syntaxTree.FindTokenOnLeftOfPosition(caretPosition, cancellationToken)
                                  .GetPreviousTokenIfTouchingWord(caretPosition);

            return IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token);
        }
		public override async Task<bool> IsExclusiveAsync (Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
		{
			// We're exclusive if this context could only be an object initializer and not also a
			// collection initializer. If we're initializing something that could be initialized as
			// an object or as a collection, say we're not exclusive. That way the rest of
			// intellisense can be used in the collection intitializer.
			// 
			// Consider this case:

			// class c : IEnumerable<int> 
			// { 
			// public void Add(int addend) { }
			// public int foo; 
			// }

			// void foo()
			// {
			//    var b = new c {|
			// }

			// There we could initialize b using either an object initializer or a collection
			// initializer. Since we don't know which the user will use, we'll be non-exclusive, so
			// the other providers can help the user write the collection initializer, if they want
			// to.
			var tree = await document.GetCSharpSyntaxTreeAsync (cancellationToken).ConfigureAwait (false);

			if (tree.IsInNonUserCode (position, cancellationToken)) {
				return false;
			}

			var token = tree.FindTokenOnLeftOfPosition (position, cancellationToken);
			token = token.GetPreviousTokenIfTouchingWord (position);

			if (token.Parent == null) {
				return false;
			}

			var expression = token.Parent.Parent as ExpressionSyntax;
			if (expression == null) {
				return false;
			}

			var semanticModel = await document.GetCSharpSemanticModelForNodeAsync (expression, cancellationToken).ConfigureAwait (false);
			var initializedType = semanticModel.GetTypeInfo (expression, cancellationToken).Type;
			if (initializedType == null) {
				return false;
			}

			// Non-exclusive if initializedType can be initialized as a collection.
			if (initializedType.CanSupportCollectionInitializer ()) {
				return false;
			}

			// By default, only our member names will show up.
			return true;
		}
        protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            // first try to get the #r string literal token.  If we couldn't, then we're not in a #r
            // reference directive and we immediately bail.
            SyntaxToken stringLiteral;
            if (!TryGetStringLiteralToken(tree, position, out stringLiteral, cancellationToken))
            {
                return null;
            }

            var documentPath = document.Project.IsSubmission ? null : document.FilePath;
            var textChangeSpan = this.GetTextChangeSpan(stringLiteral, position);

            var gacHelper = new GlobalAssemblyCacheCompletionHelper(this, textChangeSpan);
            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
            var snapshot = text.FindCorrespondingEditorTextSnapshot();
            if (snapshot == null)
            {
                // Passing null to GetFileSystemDiscoveryService raises an exception.
                // Instead, return here since there is no longer snapshot for this document.
                return null;
            }

            var assemblyReferenceResolver = document.Project.CompilationOptions.MetadataReferenceResolver as AssemblyReferenceResolver;
            if (assemblyReferenceResolver == null)
            {
                return null;
            }

            var metadataFileResolver = assemblyReferenceResolver.PathResolver as MetadataFileReferenceResolver;
            if (metadataFileResolver == null)
            {
                return null;
            }

            var fileSystemHelper = new FileSystemCompletionHelper(
                this, textChangeSpan,
                GetFileSystemDiscoveryService(snapshot),
                Glyph.OpenFolder,
                Glyph.Assembly,
                searchPaths: metadataFileResolver.SearchPaths,
                allowableExtensions: new[] { ".dll", ".exe" },
                exclude: path => path.Contains(","));

            var pathThroughLastSlash = this.GetPathThroughLastSlash(stringLiteral, position);
            return gacHelper.GetItems(pathThroughLastSlash, documentPath).Concat(
                fileSystemHelper.GetItems(pathThroughLastSlash, documentPath));
        }
		private async Task<IEnumerable<CompletionData>> GetSpeculativeTCompletions(CompletionEngine engine, Document document, int position, CancellationToken cancellationToken)
		{
			var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
			if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
				syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
			{
				return Enumerable.Empty<CompletionData>();
			}

			// If we're in a generic type argument context, use the start of the generic type name
			// as the position for the rest of the context checks.
			int testPosition = position;
			var leftToken = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);

			var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(leftToken.Parent, cancellationToken).ConfigureAwait(false);
			if (syntaxTree.IsGenericTypeArgumentContext(position, leftToken, cancellationToken, semanticModel))
			{
				// Walk out until we find the start of the partial written generic
				SyntaxToken nameToken;
				while (syntaxTree.IsInPartiallyWrittenGeneric(testPosition, cancellationToken, out nameToken))
				{
					testPosition = nameToken.SpanStart;
				}

				// If the user types Foo<T, automatic brace completion will insert the close brace
				// and the generic won't be "partially written".
				if (testPosition == position)
				{
					var typeArgumentList = leftToken.GetAncestor<TypeArgumentListSyntax>();
					if (typeArgumentList != null)
					{
						if (typeArgumentList.LessThanToken != default(SyntaxToken) && typeArgumentList.GreaterThanToken != default(SyntaxToken))
						{
							testPosition = typeArgumentList.LessThanToken.SpanStart;
						}
					}
				}
			}

			if ((!leftToken.GetPreviousTokenIfTouchingWord(position).IsKindOrHasMatchingText(SyntaxKind.AsyncKeyword) &&
				syntaxTree.IsMemberDeclarationContext(testPosition, contextOpt: null, validModifiers: SyntaxKindSet.AllMemberModifiers, validTypeDeclarations: SyntaxKindSet.ClassInterfaceStructTypeDeclarations, canBePartial: false, cancellationToken: cancellationToken)) ||
				syntaxTree.IsGlobalMemberDeclarationContext(testPosition, SyntaxKindSet.AllGlobalMemberModifiers, cancellationToken) ||
				syntaxTree.IsGlobalStatementContext(testPosition, cancellationToken) ||
				syntaxTree.IsDelegateReturnTypeContext(testPosition, syntaxTree.FindTokenOnLeftOfPosition(testPosition, cancellationToken), cancellationToken))
			{
				const string T = "T";
				return new [] { engine.Factory.CreateGenericData (this, T, GenericDataType.Undefined) };
			}
			return Enumerable.Empty<CompletionData>();
		}
        protected override int GetContainingClassName(Document document, SnapshotSpan fieldSpan, CancellationToken cancellationToken, ref string value, ref int hasDefaultValue)
        {
            // Find the nearest encolsing type declaration and use its name
            var syntaxTree = document.GetCSharpSyntaxTreeAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var type = syntaxTree.FindTokenOnLeftOfPosition(fieldSpan.Start.Position, cancellationToken).GetAncestor<TypeDeclarationSyntax>();

            if (type != null)
            {
                value = type.Identifier.ToString();

                if (!string.IsNullOrWhiteSpace(value))
                {
                    hasDefaultValue = 1;
                }
            }

            return VSConstants.S_OK;
        }
		//		public async Task<IList<TextChange>> GetFormattingChangesAsync(Document document, char typedChar, int caretPosition, CancellationToken cancellationToken)
		//		{
		//			var formattingRules = this.GetFormattingRules(document, caretPosition);
		//
		//			// first, find the token user just typed.
		//			SyntaxToken token = await GetTokenBeforeTheCaretAsync(document, caretPosition, cancellationToken).ConfigureAwait(false);
		//
		//			if (token.IsMissing ||
		//				!ValidSingleOrMultiCharactersTokenKind(typedChar, token.Kind()) ||
		//				token.IsKind(SyntaxKind.EndOfFileToken, SyntaxKind.None))
		//			{
		//				return null;
		//			}
		//
		//			var service = document.GetLanguageService<ISyntaxFactsService>();
		//			if (service != null && service.IsInNonUserCode(token.SyntaxTree, caretPosition, cancellationToken))
		//			{
		//				return null;
		//			}
		//
		//			// Check to see if any of the below. If not, bail.
		//			// case 1: The token is ')' and the parent is an using statement.
		//			// case 2: The token is ':' and the parent is either labelled statement or case switch or default switch
		//			if (TokenShouldNotFormatOnTypeChar(token))
		//			{
		//				return null;
		//			}
		//
		//			// if formatting range fails, do format token one at least
		//			var changes = await FormatRangeAsync(document, token, formattingRules, cancellationToken).ConfigureAwait(false);
		//			if (changes.Count > 0)
		//			{
		//				return changes;
		//			}
		//
		//			// if we can't, do normal smart indentation
		//			return await FormatTokenAsync(document, token, formattingRules, cancellationToken).ConfigureAwait(false);
		//		}

		public static async Task<SyntaxToken> GetTokenBeforeTheCaretAsync(Document document, int caretPosition, CancellationToken cancellationToken)
		{
			var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

			var position = Math.Max(0, caretPosition - 1);
			var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);
			var token = root.FindToken(position, findInsideTrivia: true);
			return token;
		}
        private async Task<CompletionItem> GetBuilderAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (triggerInfo.TriggerReason == CompletionTriggerReason.TypeCharCommand)
            {
                var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                if (triggerInfo.IsDebugger && triggerInfo.IsImmediateWindow)
                {
                    // Aggressive Intellisense in the debugger: always show the builder 
                    return new CompletionItem(this, "", CompletionUtilities.GetTextChangeSpan(text, position), isBuilder: true);
                }

                var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);
                token = token.GetPreviousTokenIfTouchingWord(position);
                if (token.Kind() == SyntaxKind.None)
                {
                    return null;
                }

                var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(token.Parent, cancellationToken).ConfigureAwait(false);
                var typeInferrer = document.GetLanguageService<ITypeInferenceService>();

                if (IsLambdaExpression(semanticModel, position, token, typeInferrer, cancellationToken))
                {
                    return new CompletionItem(this, CSharpFeaturesResources.LambdaExpression,
                        CompletionUtilities.GetTextChangeSpan(text, position),
                        CSharpFeaturesResources.AutoselectDisabledDueToPotentialLambdaDeclaration.ToSymbolDisplayParts(),
                        isBuilder: true);
                }
                else if (IsAnonymousObjectCreation(token))
                {
                    return new CompletionItem(this, CSharpFeaturesResources.MemberName,
                        CompletionUtilities.GetTextChangeSpan(text, position),
                        CSharpFeaturesResources.AutoselectDisabledDueToPossibleExplicitlyNamesAnonTypeMemCreation.ToSymbolDisplayParts(),
                        isBuilder: true);
                }
                else if (token.IsPreProcessorExpressionContext())
                {
                    return new CompletionItem(this, "", CompletionUtilities.GetTextChangeSpan(text, position), isBuilder: true);
                }
                else if (IsImplicitArrayCreation(semanticModel, token, position, typeInferrer, cancellationToken))
                {
                    return new CompletionItem(this, CSharpFeaturesResources.ImplicitArrayCreation,
                        CompletionUtilities.GetTextChangeSpan(text, position),
                        CSharpFeaturesResources.AutoselectDisabledDueToPotentialImplicitArray.ToSymbolDisplayParts(),
                        isBuilder: true);
                }
                else
                {
                    return token.IsKindOrHasMatchingText(SyntaxKind.FromKeyword) || token.IsKindOrHasMatchingText(SyntaxKind.JoinKeyword)
                        ? new CompletionItem(this, CSharpFeaturesResources.RangeVariable,
                            CompletionUtilities.GetTextChangeSpan(text, position),
                            CSharpFeaturesResources.AutoselectDisabledDueToPotentialRangeVariableDecl.ToSymbolDisplayParts(),
                        isBuilder: true)
                        : null;
                }
            }

            return null;
        }
		internal static async Task<IList<MemberDeclarationSyntax>> GetSelectedMembersAsync(
			Document document, TextSpan textSpan, CancellationToken cancellationToken)
		{
			var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
			return tree.GetMembersInSpan(textSpan, cancellationToken);
		}
        protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(
            Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            if (syntaxTree.IsInNonUserCode(position, cancellationToken))
            {
                return null;
            }

            var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);
            token = token.GetPreviousTokenIfTouchingWord(position);

            if (token.Kind() != SyntaxKind.OpenParenToken && token.Kind() != SyntaxKind.CommaToken)
            {
                return null;
            }

            var attributeArgumentList = token.Parent as AttributeArgumentListSyntax;
            var attributeSyntax = token.Parent.Parent as AttributeSyntax;
            if (attributeSyntax == null || attributeArgumentList == null)
            {
                return null;
            }

            // We actually want to collect two sets of named parameters to present the user.  The
            // normal named parameters that come from the attribute constructors.  These will be
            // presented like "foo:".  And also the named parameters that come from the writable
            // fields/properties in the attribute.  These will be presented like "bar =".  

            var existingNamedParameters = GetExistingNamedParameters(attributeArgumentList, position);

            var workspace = document.Project.Solution.Workspace;
            var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attributeSyntax, cancellationToken).ConfigureAwait(false);
            var nameColonItems = await GetNameColonItemsAsync(workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false);
            var nameEqualsItems = await GetNameEqualsItemsAsync(workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false);

            // If we're after a name= parameter, then we only want to show name= parameters.
            if (IsAfterNameEqualsArgument(token))
            {
                return nameEqualsItems;
            }

            return nameColonItems.Concat(nameEqualsItems);
        }