예제 #1
0
        /// <summary>
        /// Temporary workaround for https://devdiv.visualstudio.com/DevDiv/_workitems/edit/662639.
        /// The first call may fail with the ArgumentException coming from Mono due to ConditionalWeakTable
        /// reentrancy, however by that time the table will have already been populated.
        /// Subsequent call should not hit this problem and should succeed.
        /// TODO: remove when https://github.com/dotnet/roslyn/issues/28256 is fixed.
        /// </summary>
        public static Document GetOpenDocumentInCurrentContextWithChangesSafe(this ITextSnapshot textSnapshot)
        {
            Document document = null;

            try {
                document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            } catch {
                try {
                    document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges();
                } catch {
                }
            }

            return(document);
        }
        public static (string description, TextSpan span)? GetCurrentBlock(
            ITextSnapshot snapshot,
            int position,
            CancellationToken cancellationToken)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null || !document.SupportsSyntaxTree)
            {
                return(null);
            }

            var syntaxFactsService = document.GetLanguageService <ISyntaxFactsService>();
            var syntaxRoot         = document.GetSyntaxRootSynchronously(cancellationToken);
            var node = syntaxFactsService.GetContainingMemberDeclaration(syntaxRoot, position, useFullSpan: false);

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

            var description = syntaxFactsService.GetDisplayName(node,
                                                                DisplayNameOptions.IncludeMemberKeyword |
                                                                DisplayNameOptions.IncludeParameters |
                                                                DisplayNameOptions.IncludeType |
                                                                DisplayNameOptions.IncludeTypeParameters);

            return(description, node.Span);
        }
예제 #3
0
        /// <summary>
        /// Get <see cref="Document"/> from <see cref="Text.Extensions.GetOpenDocumentInCurrentContextWithChanges(ITextSnapshot)"/>
        /// once <see cref="IWorkspaceStatusService.WaitUntilFullyLoadedAsync(CancellationToken)"/> returns
        /// </summary>
        public static async Task <Document> GetFullyLoadedOpenDocumentInCurrentContextWithChangesAsync(
            this ITextSnapshot snapshot, IUIThreadOperationContext operationContext)
        {
            // just get a document from whatever we have
            var document = snapshot.TextBuffer.AsTextContainer().GetOpenDocumentInCurrentContext();

            if (document == null)
            {
                // we don't know about this buffer yet
                return(null);
            }

            var description = string.Format(EditorFeaturesResources.Operation_is_not_ready_for_0_yet_see_task_center_for_more_detail, document.Name);

            // partial mode is always cancellable
            using (operationContext.AddScope(allowCancellation: true, description))
            {
                var service = document.Project.Solution.Workspace.Services.GetService <IWorkspaceStatusService>();
                if (service != null)
                {
                    // TODO: decide for prototype, we don't do anything complex and just ask workspace whether it is fully loaded
                    // later we might need to go and change all these with more specific info such as document/project/solution
                    await service.WaitUntilFullyLoadedAsync(operationContext.UserCancellationToken).ConfigureAwait(false);
                }

                // get proper document
                return(snapshot.GetOpenDocumentInCurrentContextWithChanges());
            }
        }
예제 #4
0
 internal void FindReferences(ITextSnapshot snapshot, int caretPosition)
 {
     _waitIndicator.Wait(
         title: EditorFeaturesResources.Find_References,
         message: EditorFeaturesResources.Finding_references,
         action: context =>
     {
         Document document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
         if (document != null)
         {
             var service = document.Project.LanguageServices.GetService <IFindReferencesService>();
             if (service != null)
             {
                 using (Logger.LogBlock(FunctionId.CommandHandler_FindAllReference, context.CancellationToken))
                 {
                     if (!service.TryFindReferences(document, caretPosition, context))
                     {
                         foreach (var presenter in _presenters)
                         {
                             presenter.DisplayResult(DefinitionsAndReferences.Empty);
                             return;
                         }
                     }
                 }
             }
         }
     }, allowCancel: true);
 }
예제 #5
0
            public static async Task <Cache> Resolve(ITextBuffer buffer, ITextSnapshot snapshot)
            {
                var workspace = buffer.GetWorkspace();
                var document  = snapshot.GetOpenDocumentInCurrentContextWithChanges();

                if (document == null)
                {
                    // Razor cshtml returns a null document for some reason.
                    return(null);
                }

                // the ConfigureAwait() calls are important,
                // otherwise we'll deadlock VS
                var semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false);

                var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

                return(new Cache {
                    Workspace = workspace,
                    Document = document,
                    SemanticModel = semanticModel,
                    SyntaxRoot = syntaxRoot,
                    Snapshot = snapshot
                });
            }
        public static bool GetCurrentBlock(
            ITextSnapshot snapshot,
            int position,
            CancellationToken cancellationToken,
            ref string description,
            ref TextSpan span)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null || !document.SupportsSyntaxTree)
            {
                return(false);
            }

            var syntaxFactsService = document.Project.LanguageServices.GetService <ISyntaxFactsService>();
            var syntaxRoot         = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var node = syntaxFactsService.GetContainingMemberDeclaration(syntaxRoot, position, useFullSpan: false);

            if (node == null)
            {
                return(false);
            }

            description = syntaxFactsService.GetDisplayName(node,
                                                            DisplayNameOptions.IncludeMemberKeyword |
                                                            DisplayNameOptions.IncludeParameters |
                                                            DisplayNameOptions.IncludeType |
                                                            DisplayNameOptions.IncludeTypeParameters);
            span = node.Span;
            return(true);
        }
        public static bool GetCurrentBlock(
            ITextSnapshot snapshot,
            int position,
            CancellationToken cancellationToken,
            ref string description,
            ref TextSpan span)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return(false);
            }

            var syntaxFactsService = document.Project.LanguageServices.GetService <ISyntaxFactsService>();
            var syntaxRoot         = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var node = syntaxFactsService.GetContainingMemberDeclaration(syntaxRoot, position, useFullSpan: false);

            if (node == null)
            {
                return(false);
            }

            var semanticModel = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var symbol        = semanticModel.GetDeclaredSymbol(node, cancellationToken);

            if (symbol == null)
            {
                return(false);
            }

            description = symbol.ToMinimalDisplayString(semanticModel, position);
            span        = node.Span;
            return(true);
        }
예제 #8
0
        public static SyntaxToken FindToken(this ITextSnapshot snapshot, int position, CancellationToken cancellationToken)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return(default);
예제 #9
0
 internal void FindReferences(ITextSnapshot snapshot, int caretPosition)
 {
     _waitIndicator.Wait(
         title: EditorFeaturesResources.FindReferences,
         message: EditorFeaturesResources.FindingReferences,
         action: context =>
     {
         Document document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
         if (document != null)
         {
             var service = document.Project.LanguageServices.GetService <IFindReferencesService>();
             if (service != null)
             {
                 if (!service.TryFindReferences(document, caretPosition, context))
                 {
                     foreach (var presenter in _presenters)
                     {
                         presenter.DisplayResult(document.Project.Solution, SpecializedCollections.EmptyEnumerable <ReferencedSymbol>());
                         return;
                     }
                 }
             }
         }
     }, allowCancel: true);
 }
예제 #10
0
        public static async Task <Tuple <string, TextSpan> > GetCurrentBlockAsync(
            ITextSnapshot snapshot,
            int position,
            CancellationToken cancellationToken)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null || !document.SupportsSyntaxTree)
            {
                return(null);
            }

            var syntaxFactsService = document.Project.LanguageServices.GetService <ISyntaxFactsService>();
            var syntaxRoot         = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var node = syntaxFactsService.GetContainingMemberDeclaration(syntaxRoot, position, useFullSpan: false);

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

            string description = syntaxFactsService.GetDisplayName(node,
                                                                   DisplayNameOptions.IncludeMemberKeyword |
                                                                   DisplayNameOptions.IncludeParameters |
                                                                   DisplayNameOptions.IncludeType |
                                                                   DisplayNameOptions.IncludeTypeParameters);

            return(Tuple.Create(description, node.Span));
        }
        public async Task <IEnumerable <CaretAdornmentData> > GetCaretAdornmentDataAsync(ITextSnapshot textSnapshot, int[] caretMemberHashcodes)
        {
            if (caretMemberHashcodes == null || caretMemberHashcodes.Length == 0)
            {
                return(Enumerable.Empty <CaretAdornmentData>());
            }

            var document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return(GetTextCaretAdornmentData(textSnapshot, caretMemberHashcodes));
            }

            var syntaxTree = await document.GetSyntaxTreeAsync();

            if (syntaxTree == null)
            {
                return(GetTextCaretAdornmentData(textSnapshot, caretMemberHashcodes));
            }

            var rootNode = await syntaxTree.GetRootAsync();

            return(GetRoslynCaretAdornmentData(caretMemberHashcodes, rootNode));
        }
        private bool PossibleTypeArgument(ITextSnapshot snapshot, SyntaxToken token, CancellationToken cancellationToken)
        {
            var node = token.Parent as BinaryExpressionSyntax;

            // type argument can be easily ambiguous with normal < operations
            if (node == null || node.Kind() != SyntaxKind.LessThanExpression || node.OperatorToken != token)
            {
                return false;
            }

            // use binding to see whether it is actually generic type or method 
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (document == null)
            {
                return false;
            }

            var model = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken);

            // Analyze node on the left of < operator to verify if it is a generic type or method.
            var leftNode = node.Left;
            if (leftNode is ConditionalAccessExpressionSyntax)
            {
                // If node on the left is a conditional access expression, get the member binding expression 
                // from the innermost conditional access expression, which is the left of < operator. 
                // e.g: Case a?.b?.c< : we need to get the conditional access expression .b?.c and analyze its
                // member binding expression (the .c) to see if it is a generic type/method.
                // Case a?.b?.c.d< : we need to analyze .c.d
                // Case a?.M(x => x?.P)?.M2< : We need to analyze .M2
                leftNode = leftNode.GetInnerMostConditionalAccessExpression().WhenNotNull;
            }

            var info = model.GetSymbolInfo(leftNode, cancellationToken);
            return info.CandidateSymbols.Any(IsGenericTypeOrMethod);
        }
예제 #13
0
        private (Document, IGoToImplementationService, IFindUsagesService) GetDocumentAndServices(ITextSnapshot snapshot)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            return(document,
                   document?.GetLanguageService <IGoToImplementationService>(),
                   document?.GetLanguageService <IFindUsagesService>());
        }
예제 #14
0
        private static (Document, IGoToDefinitionService) GetDocumentAndService(
            ITextSnapshot snapshot
            )
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            return(document, document?.GetLanguageService <IGoToDefinitionService>());
        }
예제 #15
0
        public static Document GetDocument(this IWpfTextView wpfTextView)
        {
            if (wpfTextView == null)
            {
                return(null);
            }
            ITextSnapshot currentSnapshot = wpfTextView.TextBuffer.CurrentSnapshot;

            return(currentSnapshot.GetOpenDocumentInCurrentContextWithChanges());
        }
예제 #16
0
 internal static bool TryExecuteCommand(
     ITextSnapshot snapshot,
     int caretPosition,
     CommandExecutionContext context
     ) =>
 TryExecuteCommand(
     snapshot.GetOpenDocumentInCurrentContextWithChanges(),
     caretPosition,
     context
     );
예제 #17
0
 private SnapshotContext(ITextSnapshot snapshot)
 {
     _snapshot  = snapshot;
     _workspace = snapshot.TextBuffer.GetWorkspace();
     _document  = snapshot.GetOpenDocumentInCurrentContextWithChanges();
     if (_document != null)
     {
         _semanticModel = _document.GetSemanticModelAsync().Result;
         _syntaxRoot    = _document.GetSyntaxRootAsync().Result;
     }
 }
예제 #18
0
        static async Task <CodeBlock> GetAndParseSyntaxNodeAsync(ITextSnapshot snapshot, CancellationToken token)
        {
            var document         = snapshot.GetOpenDocumentInCurrentContextWithChanges();
            var parentSyntaxNode = await document.GetSyntaxRootAsync(token).ConfigureAwait(false);

            var root = new CodeBlock(null, CodeMemberType.Root, null, new SnapshotSpan(snapshot, 0, snapshot.Length), 0);

            ParseSyntaxNode(snapshot, parentSyntaxNode, root, 0, token);

            return(root);
        }
예제 #19
0
        private async Task <CodeBlock> GetandParseSyntaxNodeAsync(ITextSnapshot snapshot, CancellationToken token)
        {
            Document   document         = snapshot.GetOpenDocumentInCurrentContextWithChanges();
            SyntaxNode parentSyntaxNode = await document.GetSyntaxRootAsync(token).ConfigureAwait(false);

            CodeBlock parentCodeBlockNode = new CodeBlock(null, BlockType.Root, null, new SnapshotSpan(snapshot, 0, snapshot.Length), 0, 0);

            ParseSyntaxNode(snapshot, parentSyntaxNode, parentCodeBlockNode, token, 0);

            return(parentCodeBlockNode);
        }
        private static (Document, IFindUsagesServiceRenameOnceTypeScriptMovesToExternalAccess) GetDocumentAndService(ITextSnapshot snapshot)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

#pragma warning disable CS0618 // Type or member is obsolete
            var legacyService = document?.GetLanguageService <IFindUsagesService>();
#pragma warning restore CS0618 // Type or member is obsolete
            return(legacyService == null
                ? (document, document?.GetLanguageService <IFindUsagesServiceRenameOnceTypeScriptMovesToExternalAccess>())
                : (document, new FindUsagesServiceWrapper(legacyService)));
        }
        private static Document Format(ICommentSelectionService service, ITextSnapshot snapshot, IEnumerable <SnapshotSpan> changes, CancellationToken cancellationToken)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return(null);
            }

            var textSpans = changes.SelectAsArray(change => change.Span.ToTextSpan());

            return(service.FormatAsync(document, textSpans, cancellationToken).WaitAndGetResult(cancellationToken));
        }
예제 #22
0
        public static SyntaxToken FindToken(this ITextSnapshot snapshot, int position, CancellationToken cancellationToken)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return(default(SyntaxToken));
            }

            var root = document.GetSyntaxRootSynchronously(cancellationToken);

            return(root.FindToken(position, findInsideTrivia: true));
        }
        internal async Task UpdateFieldAdornments(ITextSnapshot textSnapshot, IEnumerable<ITextViewLine> lines)
        {
            var workspace = this.view.TextBuffer.GetWorkspace();
            var document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            var semanticModel = await document.GetSemanticModelAsync();
            var syntaxRoot = await document.GetSyntaxRootAsync();
            var fields = syntaxRoot.DescendantNodes().OfType<FieldDeclarationSyntax>().SelectMany(f => f.Declaration.Variables).ToList();
            var fieldsThatShouldBeReadOnly = fields.Where(f => ShouldBeReadOnly(f, semanticModel, workspace)).ToList();

            foreach (ITextViewLine line in lines)
            {
                this.CreateVisuals(line, fields, fieldsThatShouldBeReadOnly);
            }
        }
예제 #24
0
        private void Format(ICommentUncommentService service, ITextSnapshot snapshot, IEnumerable <ITrackingSpan> changes, CancellationToken cancellationToken)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return;
            }

            var textSpans   = changes.Select(s => s.GetSpan(snapshot)).Select(s => s.Span.ToTextSpan()).ToList();
            var newDocument = service.Format(document, textSpans, cancellationToken);

            newDocument.Project.Solution.Workspace.ApplyDocumentChanges(newDocument, cancellationToken);
        }
            public static async Task <RoslynCache> Resolve(ITextSnapshot snapshot)
            {
                var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

                if (document == null)
                {
                    return(null);
                }
                return(new RoslynCache
                {
                    SemanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false),
                    SyntaxTree = await document.GetSyntaxTreeAsync().ConfigureAwait(false),
                    Snapshot = snapshot
                });
            }
        internal bool TryExecuteCommand(ITextSnapshot snapshot, int caretPosition)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document != null)
            {
                var goToDefinitionService = document.Project.LanguageServices.GetService <IGoToDefinitionService>();
                return(TryExecuteCommand(document, caretPosition, goToDefinitionService));
            }
            else
            {
                // We didn't even have a workspace, so we can let somebody else try to handle this if they can
                return(false);
            }
        }
예제 #27
0
        public static async Task <RoslynDocument> Resolve(ITextBuffer buffer, ITextSnapshot snapshot)
        {
            var workspace     = buffer.GetWorkspace();
            var document      = snapshot.GetOpenDocumentInCurrentContextWithChanges();
            var semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false);

            var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            return(new RoslynDocument
            {
                Workspace = workspace,
                Document = document,
                SemanticModel = semanticModel,
                SyntaxRoot = syntaxRoot,
                Snapshot = snapshot
            });
        }
예제 #28
0
        async Task Initialize(RoslynTaggerAsyncState state, ITextSnapshot snapshot, CancellationToken cancellationToken)
        {
            var doc = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (doc is null)
            {
                return;
            }
            var syntaxRoot = await doc.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var semanticModel = await doc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var workspace = snapshot.TextBuffer.TryGetWorkspace();

            Debug.Assert(!state.IsInitialized);
            state.Initialize(syntaxRoot, semanticModel, workspace);
        }
예제 #29
0
        /// <summary>
        /// This method collects syntax nodes of method declarations that have too many lines of code.
        /// </summary>
        /// <param name="newSnapshot">The text snapshot containing the code to analyze.</param>
        /// <returns>Returns a list with the method declaration nodes.</returns>
        private async Task <IEnumerable <MethodDeclarationSyntax> > CollectMethodDeclarationSyntaxNodes(ITextSnapshot newSnapshot)
        {
            if (newSnapshot == null)
            {
                throw new ArgumentNullException(nameof(newSnapshot));
            }

            var currentDocument = newSnapshot.GetOpenDocumentInCurrentContextWithChanges();

            var syntaxRoot = await currentDocument.GetSyntaxRootAsync();

            var tooLongMethodDeclarations = syntaxRoot
                                            .DescendantNodes(node => true, false)
                                            .Where(node => node.Kind() == SyntaxKind.MethodDeclaration)
                                            .Select(methodDeclaration => methodDeclaration as MethodDeclarationSyntax);

            return(tooLongMethodDeclarations);
        }
        /// <summary>
        /// format given snapshot and apply text changes to buffer
        /// </summary>
        public static void FormatAndApplyToBuffer(this ITextSnapshot snapshot, TextSpan span, CancellationToken cancellationToken)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return;
            }

            var tree            = document.GetSyntaxTreeSynchronously(cancellationToken);
            var documentOptions = document.GetOptionsAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var changes         = Formatter.GetFormattedTextChanges(tree, tree.Root, SpecializedCollections.SingletonEnumerable(span), document.Workspace, documentOptions, cancellationToken);

            //using (Logger.LogBlock(FunctionId.Formatting_ApplyResultToBuffer, cancellationToken))
            {
                document.Workspace.ApplyTextChanges(document.Id, changes, cancellationToken);
            }
        }
예제 #31
0
        /// <summary>
        /// format given snapshot and apply text changes to buffer
        /// </summary>
        public static void FormatAndApplyToBuffer(this ITextSnapshot snapshot, TextSpan span, IEnumerable <IFormattingRule> rules, CancellationToken cancellationToken)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return;
            }

            rules = GetFormattingRules(document, rules, span);

            var root    = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var changes = Formatter.GetFormattedTextChanges(root, SpecializedCollections.SingletonEnumerable(span), document.Project.Solution.Workspace, options: null, rules: rules, cancellationToken: cancellationToken);

            using (Logger.LogBlock(FunctionId.Formatting_ApplyResultToBuffer, cancellationToken))
            {
                document.Project.Solution.Workspace.ApplyTextChanges(document.Id, changes, cancellationToken);
            }
        }
        /// <summary>
        /// This method collects syntax nodes of code blocks that have too many lines of code.
        /// </summary>
        /// <param name="newSnapshot">The text snapshot containing the code to analyze.</param>
        /// <returns>Returns a list with the code block syntax nodes.</returns>
        private async Task <IEnumerable <BlockSyntax> > CollectBlockSyntaxNodesAsync(ITextSnapshot newSnapshot)
        {
            if (newSnapshot == null)
            {
                throw new ArgumentNullException(nameof(newSnapshot));
            }

            var currentDocument = newSnapshot.GetOpenDocumentInCurrentContextWithChanges();

            var syntaxRoot = await currentDocument.GetSyntaxRootAsync();

            var codeBlocks = syntaxRoot
                             .DescendantNodes(node => true)
                             .Where(node => node.IsSyntaxBlock() &&
                                    (node.Parent.IsMethod() ||
                                     node.Parent.IsConstructor() ||
                                     node.Parent.IsSetter() ||
                                     node.Parent.IsGetter()))
                             .Select(block => block as BlockSyntax);

            return(codeBlocks);
        }
        private bool PossibleTypeArgument(ITextSnapshot snapshot, SyntaxToken token, CancellationToken cancellationToken)
        {
            var node = token.Parent as BinaryExpressionSyntax;

            // type argument can be easily ambiguous with normal < operations
            if (node == null || node.Kind() != SyntaxKind.LessThanExpression || node.OperatorToken != token)
            {
                return false;
            }

            // use binding to see whether it is actually generic type or method 
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (document == null)
            {
                return false;
            }

            var model = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var info = model.GetSymbolInfo(node.Left, cancellationToken);

            return info.CandidateSymbols.Any(IsGenericTypeOrMethod);
        }
        public static async Task<MultiLineCommentTaggerContext> CreateAsync(ITextSnapshot snapshot)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
            var semanticModel = await document.GetSemanticModelAsync();
            var syntaxRoot = await document.GetSyntaxRootAsync();

            return new MultiLineCommentTaggerContext(document, semanticModel, syntaxRoot, snapshot);
        }
 public SyntaxNode GetSyntaxNodeFromTextSnapshot(ITextSnapshot textSnapshot)
 {
     return textSnapshot.GetOpenDocumentInCurrentContextWithChanges().GetSyntaxRootAsync().Result;
 }
        public static async Task<SemanticFormatterContext> CreateAsync(ITextSnapshot snapshot)
        {
            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
            var semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false);
            var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            return new SemanticFormatterContext(document, semanticModel, syntaxRoot, snapshot);
        }
        private static IList<SyntaxNode> CollectSensitiveSyntaxNodes(ITextSnapshot newSnapshot)
        {
            var sensitiveSyntaxNodes = new List<SyntaxNode>();

            // [RS] NuGet package Microsoft.CodeAnalysis.EditorFeatures.Text needed for method 'GetOpenDocumentInCurrentContextWithChanges'.
            //      There it is defined in Microsoft.CodeAnalysis.Text.
            var currentDocument = newSnapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (currentDocument == null)
                return sensitiveSyntaxNodes;

            var trees = currentDocument.Project.Documents
                .Select(document => document.GetSyntaxTreeAsync().Result)
                .SkipWhile(syntaxTree => syntaxTree.Length == 0);

            var references = new[]
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.CodeBase.Substring(8)),
                MetadataReference.CreateFromFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Core.dll")
            };

            var compilation = CSharpCompilation
                .Create("CodeInCurrentProject")
                .AddReferences(references)
                .AddSyntaxTrees(trees);

            var tree = currentDocument.GetSyntaxTreeAsync().Result;
            var semanticModel = compilation.GetSemanticModel(tree);
            var treeRoot = tree.GetRoot() as CompilationUnitSyntax;

            // [RS] Collect identifier names.
            var identifiers = treeRoot.DescendantNodes().OfType<IdentifierNameSyntax>();
            foreach (var identifier in identifiers)
            {
                if (identifier.IsVar)
                    continue;

                var typeInfo = semanticModel.GetTypeInfo(identifier);

                if (typeInfo.Type != null)
                {
                    if (typeInfo.Type.AllInterfaces.Where(namedInterfaceType => namedInterfaceType.Name == "ISensitiveObject").Any())
                        sensitiveSyntaxNodes.Add(identifier);
                }
                else
                {
                    var symbolInfo = semanticModel.GetSymbolInfo(identifier);

                    if (symbolInfo.Symbol != null)
                    {
                        var namedType = symbolInfo.Symbol as INamedTypeSymbol;

                        if (namedType != null && namedType.AllInterfaces.Where(namedInterfaceType => namedInterfaceType.Name == "ISensitiveObject").Any())
                            sensitiveSyntaxNodes.Add(identifier);
                    }
                }
            }

            return sensitiveSyntaxNodes;
        }