iT邦幫忙

2025 iThome 鐵人賽

DAY 12
0

Green/Red Tree 架構

Roslyn 使用雙層樹結構來平衡效能與易用性

Green Nodes不可變節點

  • 完全不可變,可安全共享
  • 不包含父節點指標,無循環引用
  • 包含所有語法資訊 Trivia
  • 記憶體效率高,適合快取

Red Nodes導航節點

  • 包含父節點指標,支援向上導航
  • 惰性建立,按需產生
  • 提供豐富的 API 供分析工具使用
  • 包裝 Green Node 並提供位置資訊
// 簡化的 Red/Green 概念示例
public abstract class GreenNode  // 實際 Roslyn 中的不可變節點
{
    public abstract SyntaxKind Kind { get; }
    public abstract int FullWidth { get; }
    public virtual bool HasTrivia => false;
}

public abstract class SyntaxNode  // 實際 Roslyn 中的 Red 節點
{
    internal GreenNode Green { get; }
    public SyntaxNode? Parent { get; }
    public int Position { get; }
    
    // 導航 API
    public SyntaxNode? NextSibling() { /* ... */ }
    public SyntaxNode? PreviousSibling() { /* ... */ }
    public IEnumerable<SyntaxNode> Ancestors() { /* ... */ }
}

增量解析與重用

Roslyn 支援增量解析,只重新解析變更的部分:

  1. 文本變更追蹤:記錄文字的插入/刪除操作
  2. 節點重用檢測:判斷哪些節點不受變更影響
  3. 最小重解析:只解析受影響的子樹
  4. 語法樹合併:將新舊節點合併為完整樹

診斷與錯誤報告

public class Diagnostic
{
    public DiagnosticSeverity Severity { get; }
    public string Id { get; }
    public string Message { get; }
    public Location Location { get; }
    
    // 實際使用
    // CS0103: The name 'undefined' does not exist in the current context
}

// 診斷產生範例
public void ReportUndefinedVariable(SyntaxToken identifier)
{
    var diagnostic = Diagnostic.Create(
        DiagnosticDescriptor.CS0103_UndefinedName,
        identifier.GetLocation(),
        identifier.ValueText
    );
    _diagnostics.Add(diagnostic);
}

上一篇
Roslyn 語意分析
系列文
新 .NET & Azure & IoT & AI 開源技術實戰手冊 (含深入官方程式碼講解) 12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言