Open
Description
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
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);
}