예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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)}");
                }
            }
        }
예제 #4
0
            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);
            }
예제 #6
0
        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)}");
                }
            }
        }
예제 #7
0
        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);
        }
예제 #9
0
        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);
        }
예제 #11
0
        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);
        }