internal static async Task <Document> CleanupDocumentAsync( Document document, CancellationToken cancellationToken) { if (document.SupportsSyntaxTree) { var addImportOptions = await AddImportPlacementOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); document = await ImportAdder.AddImportsFromSymbolAnnotationAsync( document, Simplifier.AddImportsAnnotation, addImportOptions, cancellationToken).ConfigureAwait(false); document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, cancellationToken : cancellationToken).ConfigureAwait(false); // format any node with explicit formatter annotation document = await Formatter.FormatAsync(document, Formatter.Annotation, formattingOptions, cancellationToken).ConfigureAwait(false); // format any elastic whitespace document = await Formatter.FormatAsync(document, SyntaxAnnotation.ElasticAnnotation, formattingOptions, cancellationToken).ConfigureAwait(false); document = await CaseCorrector.CaseCorrectAsync(document, CaseCorrector.Annotation, cancellationToken).ConfigureAwait(false); } return(document); }
private async Task TestAsync(string initialText, string importsAddedText, string simplifiedText, bool safe, bool useSymbolAnnotations, Func <OptionSet, OptionSet> optionsTransform = null) { var doc = await GetDocument(initialText, useSymbolAnnotations); OptionSet options = await doc.GetOptionsAsync(); if (optionsTransform != null) { options = optionsTransform(options); } var imported = useSymbolAnnotations ? await ImportAdder.AddImportsFromSymbolAnnotationAsync(doc, safe, options) : await ImportAdder.AddImportsFromSyntaxesAsync(doc, safe, options); if (importsAddedText != null) { var formatted = await Formatter.FormatAsync(imported, SyntaxAnnotation.ElasticAnnotation, options); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(importsAddedText, actualText); } if (simplifiedText != null) { var reduced = await Simplifier.ReduceAsync(imported, options); var formatted = await Formatter.FormatAsync(reduced, SyntaxAnnotation.ElasticAnnotation, options); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(simplifiedText, actualText); } }
private static async Task TestAsync( string initialText, string importsAddedText, string simplifiedText, bool useSymbolAnnotations, Func <OptionSet, OptionSet> optionsTransform = null, bool performCheck = true ) { var doc = await GetDocument(initialText, useSymbolAnnotations); OptionSet options = await doc.GetOptionsAsync(); if (optionsTransform != null) { options = optionsTransform(options); } var imported = useSymbolAnnotations ? await ImportAdder.AddImportsFromSymbolAnnotationAsync(doc, options) : await ImportAdder.AddImportsFromSyntaxesAsync(doc, options); if (importsAddedText != null) { var formatted = await Formatter.FormatAsync( imported, SyntaxAnnotation.ElasticAnnotation, options ); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(importsAddedText, actualText); } if (simplifiedText != null) { var reduced = await Simplifier.ReduceAsync(imported, options); var formatted = await Formatter.FormatAsync( reduced, SyntaxAnnotation.ElasticAnnotation, options ); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(simplifiedText, actualText); } if (performCheck) { if (initialText == importsAddedText && importsAddedText == simplifiedText) { throw new Exception($"use {nameof(TestNoImportsAddedAsync)}"); } } }
private async Task <Document> UpdateDocumentAndAddImportsAsync(SyntaxNode oldType, SyntaxNode newType, CancellationToken cancellationToken) { var oldRoot = await _document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newDocument = _document.WithSyntaxRoot(oldRoot.ReplaceNode(oldType, newType)); var addImportOptions = await AddImportPlacementOptions.FromDocumentAsync(_document, cancellationToken).ConfigureAwait(false); newDocument = await ImportAdder.AddImportsFromSymbolAnnotationAsync(newDocument, addImportOptions, cancellationToken).ConfigureAwait(false); return(newDocument); }
private async Task <Document> UpdateDocumentAndAddImportsAsync(SyntaxNode oldType, SyntaxNode newType, CancellationToken cancellationToken) { var oldRoot = await _document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newDocument = _document.WithSyntaxRoot(oldRoot.ReplaceNode(oldType, newType)); // fallback options: https://github.com/dotnet/roslyn/issues/60794 var addImportOptions = await _document.GetAddImportPlacementOptionsAsync(fallbackOptions : null, cancellationToken).ConfigureAwait(false); newDocument = await ImportAdder.AddImportsFromSymbolAnnotationAsync(newDocument, addImportOptions, cancellationToken).ConfigureAwait(false); return(newDocument); }
private static async Task TestAsync( string initialText, string importsAddedText, string simplifiedText, bool useSymbolAnnotations, bool placeSystemNamespaceFirst = true, bool placeImportsInsideNamespaces = false, bool performCheck = true) { var doc = await GetDocument(initialText, useSymbolAnnotations); var addImportOptions = new AddImportPlacementOptions() { PlaceSystemNamespaceFirst = placeSystemNamespaceFirst, UsingDirectivePlacement = new CodeStyleOption2 <AddImportPlacement>(placeImportsInsideNamespaces ? AddImportPlacement.InsideNamespace : AddImportPlacement.OutsideNamespace, NotificationOption2.None), }; var formattingOptions = CSharpSyntaxFormattingOptions.Default; var simplifierOptions = CSharpSimplifierOptions.Default; var imported = useSymbolAnnotations ? await ImportAdder.AddImportsFromSymbolAnnotationAsync(doc, addImportOptions, CancellationToken.None) : await ImportAdder.AddImportsFromSyntaxesAsync(doc, addImportOptions, CancellationToken.None); if (importsAddedText != null) { var formatted = await Formatter.FormatAsync(imported, SyntaxAnnotation.ElasticAnnotation, formattingOptions, CancellationToken.None); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(importsAddedText, actualText); } if (simplifiedText != null) { var reduced = await Simplifier.ReduceAsync(imported, simplifierOptions, CancellationToken.None); var formatted = await Formatter.FormatAsync(reduced, SyntaxAnnotation.ElasticAnnotation, formattingOptions, CancellationToken.None); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(simplifiedText, actualText); } if (performCheck) { if (initialText == importsAddedText && importsAddedText == simplifiedText) { throw new Exception($"use {nameof(TestNoImportsAddedAsync)}"); } } }
private static async Task TestAsync( string initialText, string importsAddedText, string simplifiedText, bool useSymbolAnnotations, bool placeSystemNamespaceFirst = true, bool placeImportsInsideNamespaces = false, bool performCheck = true) { var doc = await GetDocument(initialText, useSymbolAnnotations); var addImportOptions = new AddImportPlacementOptions( PlaceSystemNamespaceFirst: placeSystemNamespaceFirst, PlaceImportsInsideNamespaces: placeImportsInsideNamespaces, AllowInHiddenRegions: false); var imported = useSymbolAnnotations ? await ImportAdder.AddImportsFromSymbolAnnotationAsync(doc, addImportOptions, CancellationToken.None) : await ImportAdder.AddImportsFromSyntaxesAsync(doc, addImportOptions, CancellationToken.None); if (importsAddedText != null) { var formatted = await Formatter.FormatAsync(imported, SyntaxAnnotation.ElasticAnnotation); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(importsAddedText, actualText); } if (simplifiedText != null) { var reduced = await Simplifier.ReduceAsync(imported); var formatted = await Formatter.FormatAsync(reduced, SyntaxAnnotation.ElasticAnnotation); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(simplifiedText, actualText); } if (performCheck) { if (initialText == importsAddedText && importsAddedText == simplifiedText) { throw new Exception($"use {nameof(TestNoImportsAddedAsync)}"); } } }
private async Task <Document> GetEditAsync( Solution solution, INamespaceOrTypeSymbol destination, Func <SyntaxNode, CodeGenerationOptions, IList <bool>?, CancellationToken, SyntaxNode> declarationTransform, CodeGenerationOptions?options, CancellationToken cancellationToken) { options ??= CodeGenerationOptions.Default; var(destinationDeclaration, availableIndices) = await this.FindMostRelevantDeclarationAsync(solution, destination, options, cancellationToken).ConfigureAwait(false); if (destinationDeclaration == null) { throw new ArgumentException(WorkspacesResources.Could_not_find_location_to_generation_symbol_into); } var destinationTree = destinationDeclaration.SyntaxTree; var oldDocument = solution.GetRequiredDocument(destinationTree); if (options.Options is null) { var documentOptions = await oldDocument.GetOptionsAsync(cancellationToken).ConfigureAwait(false); options = options.With(options: documentOptions); } var transformedDeclaration = declarationTransform(destinationDeclaration, options, availableIndices, cancellationToken); var root = await destinationTree.GetRootAsync(cancellationToken).ConfigureAwait(false); var currentRoot = root.ReplaceNode(destinationDeclaration, transformedDeclaration); var newDocument = oldDocument.WithSyntaxRoot(currentRoot); if (options.AddImports) { newDocument = await ImportAdder.AddImportsFromSymbolAnnotationAsync( newDocument, await newDocument.GetOptionsAsync(cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); } return(newDocument); }
internal static async Task <Document> CleanupDocumentAsync( Document document, CodeCleanupOptions options, CancellationToken cancellationToken) { document = await ImportAdder.AddImportsFromSymbolAnnotationAsync( document, Simplifier.AddImportsAnnotation, options.AddImportOptions, cancellationToken).ConfigureAwait(false); document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, options.SimplifierOptions, cancellationToken).ConfigureAwait(false); // format any node with explicit formatter annotation document = await Formatter.FormatAsync(document, Formatter.Annotation, options.FormattingOptions, cancellationToken).ConfigureAwait(false); // format any elastic whitespace document = await Formatter.FormatAsync(document, SyntaxAnnotation.ElasticAnnotation, options.FormattingOptions, cancellationToken).ConfigureAwait(false); document = await CaseCorrector.CaseCorrectAsync(document, CaseCorrector.Annotation, cancellationToken).ConfigureAwait(false); return(document); }
private async Task <Document> GetEditAsync( CodeGenerationSolutionContext context, INamespaceOrTypeSymbol destination, Func <SyntaxNode, TCodeGenerationContextInfo, IList <bool>?, CancellationToken, SyntaxNode> declarationTransform, CancellationToken cancellationToken) { var(destinationDeclaration, availableIndices) = await FindMostRelevantDeclarationAsync(context.Solution, destination, context.Context.BestLocation, cancellationToken).ConfigureAwait(false); if (destinationDeclaration == null) { throw new ArgumentException(WorkspacesResources.Could_not_find_location_to_generation_symbol_into); } var destinationTree = destinationDeclaration.SyntaxTree; var oldDocument = context.Solution.GetRequiredDocument(destinationTree); var codeGenOptions = await oldDocument.GetCodeGenerationOptionsAsync(context.FallbackOptions, cancellationToken).ConfigureAwait(false); var info = (TCodeGenerationContextInfo)codeGenOptions.GetInfo(context.Context, destinationDeclaration.SyntaxTree.Options); var transformedDeclaration = declarationTransform(destinationDeclaration, info, availableIndices, cancellationToken); var root = await destinationTree.GetRootAsync(cancellationToken).ConfigureAwait(false); var currentRoot = root.ReplaceNode(destinationDeclaration, transformedDeclaration); var newDocument = oldDocument.WithSyntaxRoot(currentRoot); if (context.Context.AddImports) { var addImportsOptions = await newDocument.GetAddImportPlacementOptionsAsync(context.FallbackOptions, cancellationToken).ConfigureAwait(false); newDocument = await ImportAdder.AddImportsFromSymbolAnnotationAsync(newDocument, addImportsOptions, cancellationToken).ConfigureAwait(false); } return(newDocument); }
public async Task TestDoNotAddDuplicateImportIfNamespaceIsDefinedInSourceAndExternalAssembly(bool useSymbolAnnotations) { var externalCode = @"namespace N.M { public class A : System.Attribute { } }"; var code = @"using System; using N.M; class C { public void M1(String p1) { } public void M2([A] String p2) { } }"; var otherAssemblyReference = GetInMemoryAssemblyReferenceForCode(externalCode); var ws = new AdhocWorkspace(); var emptyProject = ws.AddProject( ProjectInfo.Create( ProjectId.CreateNewId(), VersionStamp.Default, "test", "test.dll", LanguageNames.CSharp, metadataReferences: new[] { TestMetadata.Net451.mscorlib })); var project = emptyProject .AddMetadataReferences(new[] { otherAssemblyReference }) .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); project = project.AddDocument("duplicate.cs", externalCode).Project; var document = project.AddDocument("test.cs", code); var compilation = await document.Project.GetCompilationAsync(CancellationToken.None); var compilerDiagnostics = compilation.GetDiagnostics(CancellationToken.None); Assert.Empty(compilerDiagnostics.Where(d => d.Severity == DiagnosticSeverity.Error)); var attribute = compilation.GetTypeByMetadataName("N.M.A"); var syntaxRoot = await document.GetSyntaxRootAsync(CancellationToken.None).ConfigureAwait(false); SyntaxNode p1SyntaxNode = syntaxRoot.DescendantNodes().OfType <ParameterSyntax>().FirstOrDefault(); // Add N.M.A attribute to p1. var editor = await DocumentEditor.CreateAsync(document, CancellationToken.None).ConfigureAwait(false); var attributeSyntax = editor.Generator.Attribute(editor.Generator.TypeExpression(attribute)); editor.AddAttribute(p1SyntaxNode, attributeSyntax); var documentWithAttribute = editor.GetChangedDocument(); var addImportOptions = new AddImportPlacementOptions(); var formattingOptions = CSharpSyntaxFormattingOptions.Default; // Add namespace import. var imported = useSymbolAnnotations ? await ImportAdder.AddImportsFromSymbolAnnotationAsync(documentWithAttribute, addImportOptions, CancellationToken.None).ConfigureAwait(false) : await ImportAdder.AddImportsFromSyntaxesAsync(documentWithAttribute, addImportOptions, CancellationToken.None).ConfigureAwait(false); var formatted = await Formatter.FormatAsync(imported, formattingOptions, CancellationToken.None); var actualText = (await formatted.GetTextAsync()).ToString(); Assert.Equal(@"using System; using N.M; class C { public void M1([global::N.M.A] String p1) { } public void M2([A] String p2) { } }", actualText); }