private static async Task TokenFormatWorkerAsync(TestWorkspace workspace, ITextBuffer buffer, int indentationLine, char ch)
        {
            var document = buffer.CurrentSnapshot.GetRelatedDocumentsWithChanges().First();
            var root     = (CompilationUnitSyntax)await document.GetSyntaxRootAsync();

            var line = root.GetText().Lines[indentationLine];

            var index = line.ToString().LastIndexOf(ch);

            Assert.InRange(index, 0, int.MaxValue);

            // get token
            var position = line.Start + index;
            var token    = root.FindToken(position);

            var formattingRuleProvider = workspace.Services.GetService <IHostDependentFormattingRuleFactoryService>();

            var rules = ImmutableArray.Create(formattingRuleProvider.CreateRule(document, position)).AddRange(Formatter.GetDefaultFormattingRules(document));

            var options = await IndentationOptions.FromDocumentAsync(document, CancellationToken.None);

            var formatter = new CSharpSmartTokenFormatter(options, rules, root);
            var changes   = await formatter.FormatTokenAsync(token, CancellationToken.None);

            ApplyChanges(buffer, changes);
        }
            private bool TryStart(CancellationToken cancellationToken)
            {
                this.AssertIsForeground();
                var closingSnapshotPoint = ClosingPoint.GetPoint(SubjectBuffer.CurrentSnapshot);

                if (closingSnapshotPoint.Position < 1)
                {
                    Debug.Fail("The closing point was not found at the expected position.");
                    return(false);
                }

                var openingSnapshotPoint = closingSnapshotPoint.Subtract(1);

                if (openingSnapshotPoint.GetChar() != OpeningBrace)
                {
                    // there is a bug in editor brace completion engine on projection buffer that already fixed in vs_pro. until that is FIed to use
                    // I will make this not to assert
                    // Debug.Fail("The opening brace was not found at the expected position.");
                    return(false);
                }

                OpeningPoint = SubjectBuffer.CurrentSnapshot.CreateTrackingPoint(openingSnapshotPoint, PointTrackingMode.Positive);

                var context = GetBraceCompletionContext();

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

                var braceResult = _service.GetBraceCompletionAsync(context.Value, cancellationToken).WaitAndGetResult(cancellationToken);

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

                using var caretPreservingTransaction = new CaretPreservingEditTransaction(EditorFeaturesResources.Brace_Completion, _undoHistory, _editorOperations);

                // Apply the change to complete the brace.
                ApplyBraceCompletionResult(braceResult.Value);

                // switch the closing point from positive to negative tracking so that the closing point stays against the closing brace
                ClosingPoint = SubjectBuffer.CurrentSnapshot.CreateTrackingPoint(ClosingPoint.GetPoint(SubjectBuffer.CurrentSnapshot), PointTrackingMode.Negative);

                var contextAfterStart = GetBraceCompletionContext();

                if (contextAfterStart != null)
                {
                    var options           = IndentationOptions.FromDocumentAsync(contextAfterStart.Value.Document, cancellationToken).WaitAndGetResult(cancellationToken);
                    var changesAfterStart = _service.GetTextChangesAfterCompletionAsync(contextAfterStart.Value, options, cancellationToken).WaitAndGetResult(cancellationToken);
                    if (changesAfterStart != null)
                    {
                        ApplyBraceCompletionResult(changesAfterStart.Value);
                    }
                }

                caretPreservingTransaction.Complete();
                return(true);
            }
            public void PostReturn()
            {
                this.AssertIsForeground();
                if (this.GetCaretPosition().HasValue)
                {
                    var closingSnapshotPoint = ClosingPoint.GetPoint(SubjectBuffer.CurrentSnapshot);

                    if (closingSnapshotPoint.Position > 0 && HasNoForwardTyping(this.GetCaretPosition().Value, closingSnapshotPoint.Subtract(1)))
                    {
                        var context = GetBraceCompletionContext();
                        if (context == null)
                        {
                            return;
                        }

                        var options            = IndentationOptions.FromDocumentAsync(context.Value.Document, CancellationToken.None).WaitAndGetResult(CancellationToken.None);
                        var changesAfterReturn = _service.GetTextChangeAfterReturnAsync(context.Value, options, CancellationToken.None).WaitAndGetResult(CancellationToken.None);
                        if (changesAfterReturn != null)
                        {
                            using var caretPreservingTransaction = new CaretPreservingEditTransaction(EditorFeaturesResources.Brace_Completion, _undoHistory, _editorOperations);
                            ApplyBraceCompletionResult(changesAfterReturn.Value);
                            caretPreservingTransaction.Complete();
                        }
                    }
                }
            }
        private Indenter GetIndenter(Document document, int lineNumber, FormattingOptions.IndentStyle indentStyle, CancellationToken cancellationToken)
        {
            var options      = IndentationOptions.FromDocumentAsync(document, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken);
            var syntacticDoc = SyntacticDocument.CreateAsync(document, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken);

            var sourceText       = syntacticDoc.Root.SyntaxTree.GetText(cancellationToken);
            var lineToBeIndented = sourceText.Lines[lineNumber];

            var formattingRules = GetFormattingRules(document, lineToBeIndented.Start, indentStyle);

            return(new Indenter(this, syntacticDoc, formattingRules, options, lineToBeIndented, cancellationToken));
        }
        private Indenter GetIndenter(Document document, int lineNumber, FormattingOptions2.IndentStyle indentStyle, CancellationToken cancellationToken)
        {
            var syntaxFormatting = this.SyntaxFormatting;

#if CODE_STYLE
            var tree = document.GetSyntaxTreeAsync(cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken);
            Contract.ThrowIfNull(tree);

            var options            = document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(tree);
            var indentationOptions = new IndentationOptions(
                syntaxFormatting.GetFormattingOptions(options),
                new AutoFormattingOptions(FormatOnReturn: true, FormatOnTyping: true, FormatOnSemicolon: true, FormatOnCloseBrace: true),
                indentStyle);
#else
            var indentationOptions = IndentationOptions.FromDocumentAsync(document, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken);
            var tree = document.GetRequiredSyntaxTreeSynchronously(cancellationToken);
#endif

            var sourceText       = tree.GetText(cancellationToken);
            var lineToBeIndented = sourceText.Lines[lineNumber];

#if CODE_STYLE
            var baseIndentationRule = NoOpFormattingRule.Instance;
#else
            var workspace             = document.Project.Solution.Workspace;
            var formattingRuleFactory = workspace.Services.GetRequiredService <IHostDependentFormattingRuleFactoryService>();
            var baseIndentationRule   = formattingRuleFactory.CreateRule(document, lineToBeIndented.Start);
#endif

            var formattingRules = ImmutableArray.Create(
                baseIndentationRule,
                this.GetSpecializedIndentationFormattingRule(indentStyle)).AddRange(
                syntaxFormatting.GetDefaultFormattingRules());

            var smartTokenFormatter = CreateSmartTokenFormatter(
                (TSyntaxRoot)tree.GetRoot(cancellationToken), lineToBeIndented, indentationOptions, baseIndentationRule);
            return(new Indenter(this, tree, formattingRules, indentationOptions, lineToBeIndented, smartTokenFormatter, cancellationToken));
        }