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()); }
/// <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)); }
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); }
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); }
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()); }
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); }