增量C# Source Generator预处理器符号列表为空的问题求助
问题
我正在编写一款可用于.NET(net9.0)和Unity(6.0)项目的增量C# Source Generator,期望根据预处理器符号(如UNITY、UNITY_WEBGL)区分运行环境,分别生成Task(.NET环境)或Awaitable(Unity环境)。我编写了如下代码尝试获取预处理器符号:
public void Initialize(IncrementalGeneratorInitializationContext context) { // Add the marker attribute to the compilation context.RegisterPostInitializationOutput(ctx => { ... }); // Extract defined preprocessor symbols var compileForUnityCheck = context.CompilationProvider.Select((compilation, _) => { if (compilation is CSharpCompilation cSharpCompilation) { var parseOptions = cSharpCompilation.SyntaxTrees.FirstOrDefault()?.Options as CSharpParseOptions; if (parseOptions != null) { var preprocessorSymbols = parseOptions.PreprocessorSymbolNames; return preprocessorSymbols.Any(s => s is "UNITY_WEBGL" or "UNITY"); } } return false; }); var thingsToGenerate = context.SyntaxProvider .ForAttributeWithMetadataName( ... var combinedProvider = thingsToGenerate.Combine(compileForUnityCheck); // Generate source code for each interface found context.RegisterSourceOutput(combinedProvider, static (spc, combined) => Execute(combined, spc)); }
但断点显示获取到的预处理器符号列表为空,生成器的其余逻辑运行正常。请问如何正确获取这些预处理器符号?(开发环境:Rider,MacOS)
解决方案
直接通过单棵语法树的解析选项获取预处理器符号不可靠,因为大部分全局定义的符号会存在于编译的全局配置中,而非单棵语法树里。正确的做法是同时读取全局编译选项和语法树本地的符号:
var compileForUnityCheck = context.CompilationProvider.Select((compilation, _) => { if (compilation is CSharpCompilation cSharpCompilation) { // 获取全局编译配置中的预处理器符号 var globalSymbols = cSharpCompilation.Options.PreprocessorSymbols; // 收集所有语法树中定义的本地预处理器符号 var localSymbols = cSharpCompilation.SyntaxTrees .Select(tree => tree.Options as CSharpParseOptions) .Where(options => options != null) .SelectMany(options => options.PreprocessorSymbolNames); // 合并两类符号,检查是否存在目标Unity符号 return globalSymbols.Concat(localSymbols) .Any(s => s is "UNITY_WEBGL" or "UNITY"); } return false; });
另外调试时需注意:
- 确认测试项目已正确配置预处理器符号:Unity项目需在Player Settings中启用
UNITY等符号,.NET项目在项目属性的"生成"选项卡中添加符号。 - Rider调试Source Generator时,确保编译上下文加载了完整的项目配置,避免增量编译的部分上下文导致符号丢失。
内容的提问来源于stack exchange,提问作者Stephen Starkie
相关产品推荐
相关产品推荐

