Skip to content

Make GeneratorDriverOptions.BaseDirectory public #75387

Open
@tmat

Description

@tmat

Background and Motivation

The compiler uses this option to construct the path of a source generated file. This path is then used to generate metadata name of file-scoped types.

This path is currently only set by the compiler task to the value of CompilerGeneratedFilesOutputPath msbuild property. It does not flow from the project system in the IDE. This causes compiler crashes during EnC since the metadata names generated by the detal emit differ from those generated by the compiler during build.

Proposed API

namespace Microsoft.CodeAnalysis;

public readonly struct GeneratorDriverOptions
{
     // existing public API:
     public readonly IncrementalGeneratorOutputKind DisabledOutputs;
     public readonly bool TrackIncrementalGeneratorSteps;

     public GeneratorDriverOptions(IncrementalGeneratorOutputKind disabledOutputs);
     public GeneratorDriverOptions(IncrementalGeneratorOutputKind disabledOutputs, bool trackIncrementalGeneratorSteps);

-    internal string? BaseDirectory { get; init; }

+    /// <summary>
+    /// Absolute path to the base directory used for file paths of generated files. Usually the project's output directory unless <see cref="CommandLineArguments.GeneratedFilesOutputDirectory"/> is specified.
+    /// </summary>
+    public string? BaseDirectory { get; }

+    /// <summary>
+    /// Creates <see cref="GeneratorDriverOptions"/>.
+    /// </summary>
+    /// <param name="baseDirectory">Absolute path to the base directory used for file paths of generated files, or null.</param>
+    /// <param name="disabledOutputs"></param>
+    /// <param name="trackIncrementalGeneratorSteps"></param>
+    /// <exception cref="ArgumentException"><paramref name="baseDirectory"/> is specified but not an absolute path.</exception>
+    public GeneratorDriverOptions(IncrementalGeneratorOutputKind disabledOutputs = IncrementalGeneratorOutputKind.None, bool trackIncrementalGeneratorSteps = false, string? baseDirectory = null);
}

Update
Make baseDirectory optional.

Usage Examples

https://github.com/dotnet/roslyn/pull/75311/files#diff-e5be48a46768235a257d73711ef134c71a03f8f896de4a977012e4b85e7bc599R57

Alternative Designs

Should we make BaseDirectory non-nullable? It would only be null if the obsoleted constructors were used.

Alternative:

public readonly struct GeneratorDriverOptions
{
     // existing public API:
     public readonly IncrementalGeneratorOutputKind DisabledOutputs;
     public readonly bool TrackIncrementalGeneratorSteps;

+    [Obsolete]
     public GeneratorDriverOptions(IncrementalGeneratorOutputKind disabledOutputs);

+    [Obsolete]
     public GeneratorDriverOptions(IncrementalGeneratorOutputKind disabledOutputs, bool trackIncrementalGeneratorSteps);

+    /// <summary>
+    /// Builder that takes a Type of a source generator and a relative file path of a generated file and returns an absolute path of the file.  
+    /// The generated absolute path is used for SyntaxTree.FilePath of syntax trees parsed from the generated source file.
+    /// </summary>
+    public Func<Type, string, string> FilePathBuilder { get; }

+    /// <summary>
+    /// Creates <see cref="GeneratorDriverOptions"/>.
+    /// </summary>
+    /// <param name="filePathBuilder">Builds absolute file paths for generated files.</param>
+    /// <param name="disabledOutputs"></param>
+    /// <param name="trackIncrementalGeneratorSteps"></param>
+    /// <exception cref="ArgumentNullException"><paramref name="filePathBuilder"/> is null.</exception>
+    public GeneratorDriverOptions(Func<Type, string, string> filePathBuilder, IncrementalGeneratorOutputKind disabledOutputs = IncrementalGeneratorOutputKind.None, bool trackIncrementalGeneratorSteps = false);
}

Risks

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-CompilersConcept-APIThis issue involves adding, removing, clarification, or modification of an API.Feature Requestapi-approvedAPI was approved in API review, it can be implementedblockingAPI needs to reviewed with priority to unblock work

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions