Esempio n. 1
0
        async Task <Document> CreateStunt(IEnumerable <INamedTypeSymbol> symbols, SyntaxGenerator generator, StuntGenerator stunts, CancellationToken cancellationToken)
        {
            var(name, syntax) = stunts.CreateStunt(symbols, generator);

            // TODO: F#
            var extension = document.Project.Language == LanguageNames.CSharp ? ".cs" : ".vb";

            // The logical folder is always the split namespace, since generated code is
            // expected to be added as hidden linked files.
            var folders = naming.Namespace.Split('.');

            if (!diagnostic.Properties.TryGetValue("Location", out var file) ||
                string.IsNullOrEmpty(file))
            {
                file = Path.Combine(Path.GetDirectoryName(document.Project.FilePath), Path.Combine(folders), name + extension);
            }

            var stuntDoc = document.Project.Documents.FirstOrDefault(d => d.Name == Path.GetFileName(file) && d.Folders.SequenceEqual(folders));

            // NOTE: the environment variable tells us we're being run with AutoCodeFix enabled and
            // active, meaning we should generate files into the intermediate output path instead.
            var autoCodeFixEnabled = bool.TryParse(Environment.GetEnvironmentVariable("AutoCodeFix"), out var value) && value;

            // Update target file path if running from build-time codegen.
            if (stuntDoc == null && autoCodeFixEnabled)
            {
                // Get configured generator options to build the final path
                if (document.Project.AnalyzerOptions.GetCodeFixSettings().TryGetValue("IntermediateOutputPath", out var intermediateOutputPath))
                {
                    file = Path.Combine(intermediateOutputPath, Path.Combine(folders), name + ".g" + extension);
                }
            }

            if (stuntDoc == null)
            {
                if (document.Project.Solution.Workspace is AdhocWorkspace workspace)
                {
                    stuntDoc = workspace.AddDocument(DocumentInfo
                                                     .Create(
                                                         DocumentId.CreateNewId(document.Project.Id),
                                                         Path.GetFileName(file),
                                                         folders: folders,
                                                         filePath: file))
                               .WithSyntaxRoot(syntax);
                }
                else
                {
                    // When running the generator from design-time, ensure the folder exists.
                    // This is necessary since we link files into the Mocks/Stunts folder,
                    // which becomes a "linked" folder itself, and when adding the document,
                    // VS fails to so.
                    if (!autoCodeFixEnabled)
                    {
                        var directory = Path.Combine(Path.GetDirectoryName(document.Project.FilePath), Path.Combine(folders));
                        Directory.CreateDirectory(directory);
                    }

                    stuntDoc = document.Project.AddDocument(
                        Path.GetFileName(file),
                        syntax,
                        folders,
                        file);
                }
            }
            else
            {
                stuntDoc = stuntDoc.WithSyntaxRoot(syntax);
            }

            stuntDoc = await stunts.ApplyProcessors(stuntDoc, cancellationToken).ConfigureAwait(false);

            // This is somewhat expensive, but with the formatting, the code doesn't even compile :/
            stuntDoc = await Simplifier.ReduceAsync(stuntDoc).ConfigureAwait(false);

            if (document.Project.Language != LanguageNames.VisualBasic)
            {
                stuntDoc = await Formatter.FormatAsync(stuntDoc, Formatter.Annotation).ConfigureAwait(false);
            }

            syntax = await stuntDoc.GetSyntaxRootAsync().ConfigureAwait(false);

            stuntDoc = stuntDoc.WithSyntaxRoot(syntax);

            return(stuntDoc);
        }
Esempio n. 2
0
        async Task <Document> CreateStunt(IEnumerable <INamedTypeSymbol> symbols, SyntaxGenerator generator, StuntGenerator stunts, CancellationToken cancellationToken)
        {
            var(name, syntax) = stunts.CreateStunt(symbols, generator);

            // TODO: F#
            var extension = document.Project.Language == LanguageNames.CSharp ? ".cs" : ".vb";
            var file      = Path.Combine(Path.GetDirectoryName(document.Project.FilePath), naming.Namespace, name + extension);
            var folders   = naming.Namespace.Split('.');

            var stuntDoc = document.Project.Documents.FirstOrDefault(d => d.Name == Path.GetFileName(file) && d.Folders.SequenceEqual(folders));

            if (stuntDoc == null)
            {
                if (document.Project.Solution.Workspace is AdhocWorkspace workspace)
                {
                    stuntDoc = workspace.AddDocument(DocumentInfo
                                                     .Create(
                                                         DocumentId.CreateNewId(document.Project.Id),
                                                         Path.GetFileName(file),
                                                         folders: naming.Namespace.Split('.'),
                                                         filePath: file))
                               .WithSyntaxRoot(syntax);
                }
                else
                {
                    stuntDoc = document.Project.AddDocument(
                        Path.GetFileName(file),
                        syntax,
                        folders,
                        file);
                }
            }
            else
            {
                stuntDoc = stuntDoc.WithSyntaxRoot(syntax);
            }

            stuntDoc = await stunts.ApplyProcessors(stuntDoc, cancellationToken).ConfigureAwait(false);

            // This is somewhat expensive, but since we're adding it to the user' solution, we might
            // as well make it look great ;)
            stuntDoc = await Simplifier.ReduceAsync(stuntDoc).ConfigureAwait(false);

            if (document.Project.Language != LanguageNames.VisualBasic)
            {
                stuntDoc = await Formatter.FormatAsync(stuntDoc, Formatter.Annotation).ConfigureAwait(false);
            }

            syntax = await stuntDoc.GetSyntaxRootAsync().ConfigureAwait(false);

            return(stuntDoc.WithSyntaxRoot(syntax));
        }