Beispiel #1
0
        public async Task <ImmutableArray <TextChange> > GetFormattingChangesOnPasteAsync(
            Document document,
            TextSpan textSpan,
            DocumentOptionSet?documentOptions,
            CancellationToken cancellationToken)
        {
            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var formattingSpan = CommonFormattingHelpers.GetFormattingSpan(root, textSpan);
            var service        = document.GetRequiredLanguageService <ISyntaxFormattingService>();

            var rules = new List <AbstractFormattingRule>()
            {
                new PasteFormattingRule()
            };

            rules.AddRange(service.GetDefaultFormattingRules());

            if (documentOptions == null)
            {
                var inferredIndentationService = document.Project.Solution.Workspace.Services.GetRequiredService <IInferredIndentationService>();
                documentOptions = await inferredIndentationService.GetDocumentOptionsWithInferredIndentationAsync(document, explicitFormat : false, cancellationToken : cancellationToken).ConfigureAwait(false);
            }

            var formattingOptions = SyntaxFormattingOptions.Create(documentOptions, document.Project.Solution.Workspace.Services, document.Project.Language);
            var result            = service.GetFormattingResult(root, SpecializedCollections.SingletonEnumerable(formattingSpan), formattingOptions, rules, cancellationToken);

            return(result.GetTextChanges(cancellationToken).ToImmutableArray());
        }
Beispiel #2
0
        /// <summary>
        /// Clean up the provided spans in the node.
        /// This will only cleanup stuff that doesn't require semantic information.
        /// </summary>
        public static Task <SyntaxNode> CleanupAsync(SyntaxNode root, ImmutableArray <TextSpan> spans, OptionSet options, HostWorkspaceServices services, ImmutableArray <ICodeCleanupProvider> providers = default, CancellationToken cancellationToken = default)
        {
            var cleanupService    = services.GetLanguageServices(root.Language).GetRequiredService <ICodeCleanerService>();
            var formattingOptions = SyntaxFormattingOptions.Create(options, services, root.Language);

            return(cleanupService.CleanupAsync(root, spans, formattingOptions, services, providers, cancellationToken));
        }
        public static async Task <ImmutableArray <TextChange> > GetFormattingChangesAsync(
            Document document,
            char typedChar,
            int position,
            DocumentOptionSet documentOptions,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfFalse(document.Project.Language is LanguageNames.CSharp);
            var formattingService = document.GetRequiredLanguageService <ISyntaxFormattingService>();

            if (!await formattingService.ShouldFormatOnTypedCharacterAsync(document, typedChar, position, cancellationToken).ConfigureAwait(false))
            {
                return(ImmutableArray <TextChange> .Empty);
            }

            var services = document.Project.Solution.Workspace.Services;

            var globalOptions = document.Project.Solution.Workspace.Services.GetRequiredService <ILegacyGlobalOptionsWorkspaceService>();

            var indentationOptions = new IndentationOptions(
                SyntaxFormattingOptions.Create(documentOptions, services, document.Project.Language),
                globalOptions.GlobalOptions.GetAutoFormattingOptions(document.Project.Language));

            return(await formattingService.GetFormattingChangesOnTypedCharacterAsync(document, position, indentationOptions, cancellationToken).ConfigureAwait(false));
        }
Beispiel #4
0
        private static async Task <SyntaxFormattingOptions> GetOptionsAsync(Document document, CancellationToken cancellationToken)
        {
            var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var analyzerConfigOptions = document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(tree);

            return(SyntaxFormattingOptions.Create(analyzerConfigOptions));
        }
        public void UpdatePreview(string text)
        {
            var service   = VisualStudioMefHostServices.Create(_componentModel.GetService <ExportProvider>());
            var workspace = new PreviewWorkspace(service);
            var fileName  = "project." + (Language == "C#" ? "csproj" : "vbproj");
            var project   = workspace.CurrentSolution.AddProject(fileName, "assembly.dll", Language);

            // use the mscorlib, system, and system.core that are loaded in the current process.
            string[] references =
            {
                "mscorlib",
                "System",
                "System.Core"
            };

            var metadataService = workspace.Services.GetService <IMetadataService>();

            var referenceAssemblies = Thread.GetDomain().GetAssemblies()
                                      .Where(x => references.Contains(x.GetName(true).Name, StringComparer.OrdinalIgnoreCase))
                                      .Select(a => metadataService.GetReference(a.Location, MetadataReferenceProperties.Assembly));

            project = project.WithMetadataReferences(referenceAssemblies);

            var document = project.AddDocument("document", SourceText.From(text, Encoding.UTF8));
            var fallbackFormattingOptions = _globalOptions.GetSyntaxFormattingOptions(document.Project.LanguageServices);
            var formattingOptions         = SyntaxFormattingOptions.Create(OptionStore.GetOptions(), fallbackFormattingOptions, document.Project.LanguageServices);
            var formatted = Formatter.FormatAsync(document, formattingOptions, CancellationToken.None).WaitAndGetResult(CancellationToken.None);

            var textBuffer = _textBufferFactoryService.CreateTextBuffer(formatted.GetTextSynchronously(CancellationToken.None).ToString(), _contentType);

            var container = textBuffer.AsTextContainer();

            var projection = _projectionBufferFactory.CreateProjectionBufferWithoutIndentation(_contentTypeRegistryService,
                                                                                               _editorOptions.CreateOptions(),
                                                                                               textBuffer.CurrentSnapshot,
                                                                                               separator: "",
                                                                                               exposedLineSpans: GetExposedLineSpans(textBuffer.CurrentSnapshot).ToArray());

            var textView = _textEditorFactoryService.CreateTextView(projection,
                                                                    _textEditorFactoryService.CreateTextViewRoleSet(PredefinedTextViewRoles.Interactive));

            this.TextViewHost = _textEditorFactoryService.CreateTextViewHost(textView, setFocus: false);

            workspace.TryApplyChanges(document.Project.Solution);
            workspace.OpenDocument(document.Id, container);

            this.TextViewHost.Closed += (s, a) =>
            {
                workspace.Dispose();
                workspace = null;
            };
        }
        public void FormatWithTabs()
        {
            var code     = @"#region Assembly mscorlib
// C:\
#endregion

using System.Collections;

class F
{
    string s;
}";
            var expected = @"#region Assembly mscorlib
// C:\
#endregion

using System.Collections;

class F
{
	string s;
}";
            var tree     = SyntaxFactory.ParseCompilationUnit(code);

            var newLineText = SyntaxFactory.ElasticEndOfLine(DefaultWorkspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp));

            tree = tree.ReplaceTokens(tree.DescendantTokens(descendIntoTrivia: true)
                                      .Where(tr => tr.IsKind(SyntaxKind.EndOfDirectiveToken)), (o, r) => o.WithTrailingTrivia(o.LeadingTrivia.Add(newLineText))
                                      .WithLeadingTrivia(SyntaxFactory.TriviaList())
                                      .WithAdditionalAnnotations(SyntaxAnnotation.ElasticAnnotation));

            using var workspace = new AdhocWorkspace();

            var options = SyntaxFormattingOptions.Create(
                workspace.Options.WithChangedOption(FormattingOptions.UseTabs, LanguageNames.CSharp, true),
                workspace.Services,
                tree.Language);

            var formatted = Formatter.Format(tree, workspace.Services, options, CancellationToken.None);

            var actual = formatted.ToFullString();

            Assert.Equal(expected, actual);
        }
Beispiel #7
0
        private protected async Task AssertFormatAsync(
            string expected,
            string code,
            IEnumerable <TextSpan> spans,
            string language,
#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/44225
            bool debugMode = false,
#pragma warning restore IDE0060 // Remove unused parameter
            OptionsCollection?changedOptionSet = null,
            bool treeCompare          = true,
            ParseOptions?parseOptions = null)
        {
            using (var workspace = new AdhocWorkspace())
            {
                var project = workspace.CurrentSolution.AddProject("Project", "Project.dll", language);
                if (parseOptions != null)
                {
                    project = project.WithParseOptions(parseOptions);
                }

                var document = project.AddDocument("Document", SourceText.From(code));

                var syntaxTree = await document.GetRequiredSyntaxTreeAsync(CancellationToken.None);

                var optionSet = workspace.Options;
                if (changedOptionSet != null)
                {
                    foreach (var entry in changedOptionSet)
                    {
                        optionSet = optionSet.WithChangedOption(entry.Key, entry.Value);
                    }
                }

                var root = await syntaxTree.GetRootAsync();

                var options = SyntaxFormattingOptions.Create(optionSet, workspace.Services, root.Language);

                await AssertFormatAsync(workspace.Services, expected, root, spans.AsImmutable(), options, await document.GetTextAsync());

                // format with node and transform
                AssertFormatWithTransformation(workspace.Services, expected, root, spans, options, treeCompare, parseOptions);
            }
        }
        public void NewLineOptions_LineFeedOnly()
        {
            using var workspace = new AdhocWorkspace();
            var tree = SyntaxFactory.ParseCompilationUnit("class C\r\n{\r\n}");

            // replace all EOL trivia with elastic markers to force the formatter to add EOL back
            tree = tree.ReplaceTrivia(tree.DescendantTrivia().Where(tr => tr.IsKind(SyntaxKind.EndOfLineTrivia)), (o, r) => SyntaxFactory.ElasticMarker);

            var options = SyntaxFormattingOptions.Create(
                workspace.Options.WithChangedOption(FormattingOptions.NewLine, LanguageNames.CSharp, "\n"),
                workspace.Services,
                tree.Language);

            var formatted = Formatter.Format(tree, workspace.Services, options, CancellationToken.None);

            var actual   = formatted.ToFullString();
            var expected = "class C\n{\n}";

            Assert.Equal(expected, actual);
        }
        protected override async Task FixAllAsync(
            Document document, ImmutableArray <Diagnostic> diagnostics, SyntaxEditor editor,
            CancellationToken cancellationToken)
        {
            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            // Defer to our callback to actually make the edits for each diagnostic. In turn, it
            // will return 'true' if it made a multi-line conditional expression. In that case,
            // we'll need to explicitly format this node so we can get our special multi-line
            // formatting in VB and C#.
            var nestedEditor = new SyntaxEditor(root, document.Project.Solution.Workspace.Services);

            foreach (var diagnostic in diagnostics)
            {
                await FixOneAsync(
                    document, diagnostic, nestedEditor, cancellationToken).ConfigureAwait(false);
            }

            var changedRoot = nestedEditor.GetChangedRoot();

            // Get the language specific rule for formatting this construct and call into the
            // formatted to explicitly format things.  Note: all we will format is the new
            // conditional expression as that's the only node that has the appropriate
            // annotation on it.
            var rules = new List <AbstractFormattingRule> {
                GetMultiLineFormattingRule()
            };

#if CODE_STYLE
            var provider = GetSyntaxFormattingService();
            var options  = SyntaxFormattingOptions.Create(document.Project.AnalyzerOptions.GetAnalyzerOptionSet(root.SyntaxTree, cancellationToken));
#else
            var provider = document.Project.Solution.Workspace.Services;
            var options  = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false);
#endif
            var formattedRoot = Formatter.Format(changedRoot, SpecializedFormattingAnnotation, provider, options, rules, cancellationToken);

            changedRoot = formattedRoot;

            editor.ReplaceNode(root, changedRoot);
        }
Beispiel #10
0
        public async Task <ImmutableArray <TextChange> > GetFormattingChangesAsync(
            Document document,
            TextSpan?textSpan,
            DocumentOptionSet?documentOptions,
            CancellationToken cancellationToken)
        {
            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var span           = textSpan ?? new TextSpan(0, root.FullSpan.Length);
            var formattingSpan = CommonFormattingHelpers.GetFormattingSpan(root, span);

            if (documentOptions == null)
            {
                var inferredIndentationService = document.Project.Solution.Workspace.Services.GetRequiredService <IInferredIndentationService>();
                documentOptions = await inferredIndentationService.GetDocumentOptionsWithInferredIndentationAsync(document, explicitFormat : true, cancellationToken : cancellationToken).ConfigureAwait(false);
            }

            var services          = document.Project.Solution.Workspace.Services;
            var formattingOptions = SyntaxFormattingOptions.Create(documentOptions, services, document.Project.Language);

            return(Formatter.GetFormattedTextChanges(root, SpecializedCollections.SingletonEnumerable(formattingSpan), services, formattingOptions, cancellationToken).ToImmutableArray());
        }
Beispiel #11
0
        public override async Task <Document> RemoveUnnecessaryImportsAsync(
            Document document,
            Func <SyntaxNode, bool> predicate,
            CancellationToken cancellationToken)
        {
            predicate ??= Functions <SyntaxNode> .True;
            using (Logger.LogBlock(FunctionId.Refactoring_RemoveUnnecessaryImports_CSharp, cancellationToken))
            {
                var unnecessaryImports = await GetCommonUnnecessaryImportsOfAllContextAsync(
                    document, predicate, cancellationToken).ConfigureAwait(false);

                if (unnecessaryImports == null || unnecessaryImports.Any(import => import.OverlapsHiddenPosition(cancellationToken)))
                {
                    return(document);
                }

                var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var oldRoot = (CompilationUnitSyntax)root;
                var newRoot = (CompilationUnitSyntax) new Rewriter(document, unnecessaryImports, cancellationToken).Visit(oldRoot);

                cancellationToken.ThrowIfCancellationRequested();
#if CODE_STYLE
                var provider  = GetSyntaxFormattingService();
                var optionSet = document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(oldRoot.SyntaxTree);
                var options   = SyntaxFormattingOptions.Create(optionSet);
#else
                var provider = document.Project.Solution.Workspace.Services;
                var options  = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false);
#endif
                var spans = new List <TextSpan>();
                AddFormattingSpans(newRoot, spans, cancellationToken);
                var formattedRoot = Formatter.Format(newRoot, spans, provider, options, rules: null, cancellationToken);

                return(document.WithSyntaxRoot(formattedRoot));
            }
        }
        private void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context)
        {
            var options = SyntaxFormattingOptions.Create(context.Options.AnalyzerConfigOptionsProvider.GetOptions(context.Tree));

            FormattingAnalyzerHelper.AnalyzeSyntaxTree(context, SyntaxFormattingService, Descriptor, options);
        }