从零实现增量源生成器 · 第 7 / 17 篇
目标类型发现,为什么不能靠全文扫描
目标发现不是把所有类型扫一遍再碰运气,而是尽早缩小候选集,再把语义判断放进转换阶段。
目标发现阶段决定了生成器的第一层性能上限。你如果一开始就全量扫描所有类型、再慢慢过滤,项目稍微大一点,体验就会开始变差。
当前项目使用的是更明确的发现方式:
context.SyntaxProvider.ForAttributeWithMetadataName(
"Tutorial.ToStringGenerator.GenerateToStringAttribute",
static (node, _) => node is ClassDeclarationSyntax,
static (context, token) => GenerationSpecFactory.Create(context, token))
这里做了哪三件事
- 先按特性元数据名缩小候选范围
- 再用语法节点类型做一次快速过滤
- 最后进入工厂方法,把语法和语义组合成可生成规格
这三步拆开后,思路会清楚很多。发现阶段不直接生成代码,而是只负责回答一个问题:这个目标值不值得进入下一步。
为什么发现后不直接渲染
因为发现阶段解决的是“是不是目标”,渲染阶段解决的是“该怎么生成”。这两个问题揉在一起,排错会非常痛苦。
一旦后续要补:
- partial 约束
- static 类型限制
- 自定义
ToString冲突 - 嵌套类型约束
你就会发现,把发现和生成分开是必须的,不是风格问题。
目标发现的核心标准
越早缩小候选集越好,越晚进入复杂逻辑越稳。好的发现阶段不应该承担所有语义判断,但必须把无关输入尽早挡在门外。
教程导航
继续阅读
当前文章已经挂到教程顺序中,建议按相邻章节继续。