Example #1
0
        public static async Task <(Document containingDocument, SyntaxAnnotation typeAnnotation)> AddTypeToNewFileAsync(
            Solution solution,
            string containingNamespaceDisplay,
            string fileName,
            ProjectId projectId,
            IEnumerable <string> folders,
            INamedTypeSymbol newSymbol,
            Document hintDocument,
            CancellationToken cancellationToken)
        {
            var newDocumentId   = DocumentId.CreateNewId(projectId, debugName: fileName);
            var newDocumentPath = PathUtilities.CombinePaths(PathUtilities.GetDirectoryName(hintDocument.FilePath), fileName);

            var solutionWithInterfaceDocument = solution.AddDocument(newDocumentId, fileName, text: "", folders: folders, filePath: newDocumentPath);
            var newDocument      = solutionWithInterfaceDocument.GetRequiredDocument(newDocumentId);
            var newSemanticModel = await newDocument.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var options = new CodeGenerationOptions(
                contextLocation: newSemanticModel.SyntaxTree.GetLocation(new TextSpan()),
                generateMethodBodies: true,
                options: await newDocument.GetOptionsAsync(cancellationToken).ConfigureAwait(false));

            var namespaceParts  = containingNamespaceDisplay.Split('.').Where(s => !string.IsNullOrEmpty(s));
            var newTypeDocument = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync(
                newDocument.Project.Solution,
                newSemanticModel.GetEnclosingNamespace(0, cancellationToken),
                newSymbol.GenerateRootNamespaceOrType(namespaceParts.ToArray()),
                options : options,
                cancellationToken : cancellationToken).ConfigureAwait(false);

            var formattingSerivce = newTypeDocument.GetLanguageService <INewDocumentFormattingService>();

            if (formattingSerivce is not null)
            {
                newTypeDocument = await formattingSerivce.FormatNewDocumentAsync(newTypeDocument, hintDocument, cancellationToken).ConfigureAwait(false);
            }

            var syntaxRoot = await newTypeDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var typeAnnotation = new SyntaxAnnotation();
            var syntaxFacts    = newTypeDocument.GetRequiredLanguageService <ISyntaxFactsService>();

            var declarationNode = syntaxRoot.DescendantNodes().First(syntaxFacts.IsTypeDeclaration);
            var annotatedRoot   = syntaxRoot.ReplaceNode(declarationNode, declarationNode.WithAdditionalAnnotations(typeAnnotation));

            newTypeDocument = newTypeDocument.WithSyntaxRoot(annotatedRoot);

            var simplified = await Simplifier.ReduceAsync(newTypeDocument, cancellationToken : cancellationToken).ConfigureAwait(false);

            var formattedDocument = await Formatter.FormatAsync(simplified, cancellationToken : cancellationToken).ConfigureAwait(false);

            return(formattedDocument, typeAnnotation);
        }
Example #2
0
        public static async Task <(Document containingDocument, SyntaxAnnotation typeAnnotation)> AddTypeToNewFileAsync(
            Solution solution,
            string containingNamespaceDisplay,
            string fileName,
            ProjectId projectId,
            IEnumerable <string> folders,
            INamedTypeSymbol newSymbol,
            Document hintDocument,
            CancellationToken cancellationToken)
        {
            var newDocumentId   = DocumentId.CreateNewId(projectId, debugName: fileName);
            var newDocumentPath = PathUtilities.CombinePaths(PathUtilities.GetDirectoryName(hintDocument.FilePath), fileName);

            var solutionWithInterfaceDocument = solution.AddDocument(newDocumentId, fileName, text: "", folders: folders, filePath: newDocumentPath);
            var newDocument      = solutionWithInterfaceDocument.GetRequiredDocument(newDocumentId);
            var newSemanticModel = await newDocument.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var context = new CodeGenerationContext(
                contextLocation: newSemanticModel.SyntaxTree.GetLocation(new TextSpan()),
                generateMethodBodies: true);

            // need to remove the root namespace from the containing namespace display because it is implied
            // For C# this does nothing as there is no root namespace (root namespace is empty string)
            var generateTypeService = newDocument.GetRequiredLanguageService <IGenerateTypeService>();
            var rootNamespace       = generateTypeService.GetRootNamespace(newDocument.Project.CompilationOptions);
            var index = rootNamespace.IsEmpty() ? -1 : containingNamespaceDisplay.IndexOf(rootNamespace);
            // if we did find the root namespace as the first element, then we remove it
            // this may leave us with an extra "." character at the start, but when we split it shouldn't matter
            var namespaceWithoutRoot = index == 0
                ? containingNamespaceDisplay.Remove(index, rootNamespace.Length)
                : containingNamespaceDisplay;

            var namespaceParts  = namespaceWithoutRoot.Split('.').Where(s => !string.IsNullOrEmpty(s));
            var newTypeDocument = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync(
                newDocument.Project.Solution,
                newSemanticModel.GetEnclosingNamespace(0, cancellationToken),
                newSymbol.GenerateRootNamespaceOrType(namespaceParts.ToArray()),
                context,
                cancellationToken).ConfigureAwait(false);

            var newTypeFormattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(newTypeDocument, cancellationToken).ConfigureAwait(false);

            var formattingService = newTypeDocument.GetLanguageService <INewDocumentFormattingService>();

            if (formattingService is not null)
            {
                newTypeDocument = await formattingService.FormatNewDocumentAsync(newTypeDocument, hintDocument, newTypeFormattingOptions, cancellationToken).ConfigureAwait(false);
            }

            var syntaxRoot = await newTypeDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var typeAnnotation = new SyntaxAnnotation();
            var syntaxFacts    = newTypeDocument.GetRequiredLanguageService <ISyntaxFactsService>();

            var declarationNode = syntaxRoot.DescendantNodes().First(syntaxFacts.IsTypeDeclaration);
            var annotatedRoot   = syntaxRoot.ReplaceNode(declarationNode, declarationNode.WithAdditionalAnnotations(typeAnnotation));

            newTypeDocument = newTypeDocument.WithSyntaxRoot(annotatedRoot);

            var simplified = await Simplifier.ReduceAsync(newTypeDocument, cancellationToken : cancellationToken).ConfigureAwait(false);

            var formattedDocument = await Formatter.FormatAsync(simplified, newTypeFormattingOptions, cancellationToken).ConfigureAwait(false);

            return(formattedDocument, typeAnnotation);
        }