首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Vczh Library++ 3.0 ManagedX 語言:編譯器類型可見性檢查的實現詳解

     編輯:關於C語言

前言

在 Vczh Library++ 3.0 的開發過程中,ManagedX 這個模仿 C# 的語言近期完成了一項核心功能:編譯器對類型在其上下文中可見性的檢查。這項工作耗時約三小時,涉及複雜的符號表處理、泛型類型展開以及存取修飾符的遞歸驗證。本文將深入剖析其核心邏輯與實現細節。

ManagedX 符號表中的類型體系

ManagedX 將類型系統大幅簡化,所有類型最終歸結為三類:

  1. 子類型
  2. 類
  3. 模板類型

函數指標、基本數值類型均被視為類處理。由於類型別名在符號表中不直接體現,編譯器需在語義分析階段進行展開替換。

類型展開機制示例

考慮以下泛型類型定義:

generic<inout T>
class A
{
    generic<inout U>
    public using S = B<T, U>;
}

generic<inout T, inout U>
class B
{
    public using T = Dictionary<T, U>;
}

以 A<int>.S<string>.T 為例,其展開前後的類型結構關係如下:

  • 展開前:符號為 A<T>.S<U>.T,父類型為 A<int>.S<string>
  • 展開後:經過符號表查找別名目標(A.S = B<T,U>),替換泛型參數,最終得到 Dictionary<int, string>

這一過程涉及 TypeSymbol 的巢狀結構,包含 GetSymbol()、GetParentType()、GetGenericDeclaration() 及 GetGenericArguments() 等關鍵屬性。

核心挑戰:存取修飾符的可見性判斷

由於存在繼承關係、父子類型嵌套及類型別名,判斷 public、protected、private、internal、protected internal 的可見性變得極為複雜。核心邏輯封裝在 EnsureTypeVisibility 函數中。

演算法核心流程

  1. 收集類型層級:從目標類型向上遍歷泛型宣告與父類型,構建層級鏈
  2. 遞歸檢查泛型參數:對每層的泛型參數遞歸調用可見性檢查
  3. 獲取當前符號的存取層級:根據符號類型(類/結構/介面/類型別名/泛型參數)獲取 Accessor
  4. 判斷可見性規則:
    • 若在當前類型鏈中(thisTypes),允許 public/protected/internal/protected internal
    • 若在基類鏈中(baseTypes),允許 public/internal/protected internal(protected 需特殊處理)
    • 否則報錯:類型不可見
  5. 處理類型別名展開:遇到 TypeRename 時,根據泛型參數替換計算其真實父類型,繼續向上檢查

關鍵代碼片段解析

void EnsureTypeVisibility(
    ManagedLanguageElement* languageElement,
    ManagedTypeSymbol* type,
    const MAP& argument,
    List<ManagedTypeSymbol*>& thisTypes,
    List<ManagedTypeSymbol*>& baseTypes
) {
    // 1. 收集類型層級鏈
    List<ManagedTypeSymbol*> typeLevels;
    ManagedTypeSymbol* currentType = type;
    while (currentType) {
        typeLevels.Add(currentType);
        currentType = currentType->GetGenericDeclaration()
            ? currentType->GetGenericDeclaration()->GetParentType()
            : currentType->GetParentType();
    }

    // 2. 從外層向內層檢查
    ManagedTypeSymbol* parentType = 0;
    for (vint i = typeLevels.Count() - 1; i >= 0; i--) {
        // ... 獲取當前宣告與存取修飾符 ...
        
        // 3. 遞歸檢查泛型參數
        if (currentType->GetGenericDeclaration()) {
            FOREACH(ManagedTypeSymbol*, genericArgument, currentType->GetGenericArguments()) {
                EnsureTypeVisibility(languageElement, genericArgument, argument, thisTypes, baseTypes);
            }
        }

        // 4. 可見性判斷邏輯
        if (parentType && !thisTypes.Contains(parentType)) {
            if (baseTypes.Contains(parentType)) {
                // 基類鏈規則
            } else {
                // 外部類型規則
            }
        }

        // 5. 類型別名展開處理
        if (currentSymbol->GetSymbolType() == ManagedSymbolItem::TypeRename) {
            // 計算實際父類型
        }
    }
}

遞歸驗證策略

以 A<int>.S<string>.T 為例,驗證邏輯分解為:

  1. 檢查 A<int>.S<string> 是否可見
  2. 展開 A<int>.S<string> 得到 B<int, string>,檢查 B<int, string>.T 是否可見

注意:B<int, string> 本身的可見性在 using S = ... 的語義分析階段已驗證,此處無需重複檢查,避免產生冗餘錯誤。

基類收集輔助函數

CollectBaseTypes 負責遞歸收集指定類型的所有基類(含泛型參數替換),為可見性判斷提供 baseTypes 列表。

總結

ManagedX 的類型可見性檢查通過層級遍歷、泛型參數遞歸、存取修飾符規則匹配以及類型別名動態展開,實現了完整的編譯期類型存取控制。這一設計既處理了巢狀泛型類型的複雜性,又正確應用了 C# 風格的存取修飾符語義,為語言的型別安全奠定了堅實基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved