• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評論-2670  文章-0  trackbacks-0

                Vczh Library++3.0的山寨C#的ManagedX今天完成了一個功能,就是編譯器檢查一個類型在他上下文里面是否可用。這個過程足夠復雜,我寫了足足3個小時。

                ManagedX的符號表里面的類型已經被大大簡化了。函數指針是類,基本數字類型也是類,所以歸根結底只有
                1:子類型
                2:類
                3:模板類型

                因為某些關系,對于類型別名沒有直接在符號表里面體現出來。舉個例子:

             1 generic<inout T>
             2 class A
             3 {
             4     generic<inout U>
             5     public using S = B<T, U>;
             6 }
             7 
             8 generic<inout T, inout U>
             9 class B
            10 {
            11     public using T = Dictionary<T, U>;
            12 }

                下面的類型與符號表中類型結構的展開后關系是:

             1 ================================================
             2 A<int> ->
             3     TypeSymbol(A<int>)
             4     {
             5         GetSymbol() = A
             6         GetParentType() = 0
             7         GetGenericDeclaration() = TypeSymbol(A)
             8         {
             9             GetSymbol() = A
            10             GetParentType() = 0
            11             GetGenericDeclaration() = 0
            12             GetGenericArguments() = []
            13         }
            14         GetGenericArguments() = [int]
            15     }
            16 ================================================
            17 A<int>.S<string> ->
            18     TypeSymbol(A<int>.S<string>)
            19     {
            20         GetSymbol() = A.S
            21         GetParentType() = 0
            22         GetGenericDeclaration() = TypeSymbol(A<int>.S)
            23         {
            24             GetSymbol() = A.S
            25             GetParentType() = TypeSymbol(A<int>)
            26             GetGenericDeclaration() = 0
            27             GetGenericArguments() = []
            28         }
            29         GetGenericArguments() = [string]
            30     }
            31 ================================================
            32 A<int>.S<string>.T ->
            33     TypeSymbol(Dictionary<intstring>)
            34     {
            35         GetSymbol() = Dictionary
            36         GetParentType() = 0
            37         GetGenericDeclaration() = TypeSymbol(Dictionary)
            38         GetGenericArguments() = [intstring]
            39     }
            40 ================================================

                對于展開前的類型結構,A<int>.S<string>.T其實上是指向了GetSymbol()是A<T>.S<U>.T,而ParentType()是A<int>.S<string>的這樣一個結構。然后再經過符號表把所有類型別名的目標類型(譬如A.S就是B<T,U>)拿出來,替換掉必要的模板參數,最后獲得展開后的類型。

                因為有了繼承關系、父子類型和類型別名,所以在判斷他們的accessor(也就是public、protected、private、internal和protected internal)是否可見的時候,就非常復雜。代碼已經上傳到Vczh Library++3.0的主頁了,下面是核心函數的代碼:

              1             void EnsureTypeVisibility(
              2                 ManagedLanguageElement* languageElement,
              3                 ManagedTypeSymbol* type,
              4                 const MAP& argument,
              5                 List<ManagedTypeSymbol*>& thisTypes,
              6                 List<ManagedTypeSymbol*>& baseTypes
              7                 )
              8             {
              9                 List<ManagedTypeSymbol*> typeLevels;
             10                 {
             11                     ManagedTypeSymbol* currentType=type;
             12                     while(currentType)
             13                     {
             14                         typeLevels.Add(currentType);
             15                         currentType=currentType->GetGenericDeclaration()
             16                             ?currentType->GetGenericDeclaration()->GetParentType()
             17                             :currentType->GetParentType()
             18                             ;
             19                     }
             20                 }
             21 
             22                 ManagedTypeSymbol* parentType=0;
             23                 for(vint i=typeLevels.Count()-1;i>=0;i--)
             24                 {
             25                     ManagedTypeSymbol* currentType=typeLevels[i];
             26                     ManagedTypeSymbol* currentDeclaration=currentType->GetGenericDeclaration()
             27                         ?currentType->GetGenericDeclaration()
             28                         :currentType
             29                         ;
             30                     if(currentType->GetGenericDeclaration())
             31                     {
             32                         FOREACH(ManagedTypeSymbol*, genericArgument, currentType->GetGenericArguments())
             33                         {
             34                             EnsureTypeVisibility(languageElement, genericArgument, argument, thisTypes, baseTypes);
             35                         }
             36                     }
             37 
             38                     ManagedSymbolItem* currentSymbol=currentDeclaration->GetSymbol();
             39                     declatt::Accessor currentAccessor=declatt::Public;
             40                     switch(currentSymbol->GetSymbolType())
             41                     {
             42                     case ManagedSymbolItem::Class:
             43                     case ManagedSymbolItem::Structure:
             44                     case ManagedSymbolItem::Interface:
             45                         {
             46                             ManagedSymbolDeclaration* symbol=dynamic_cast<ManagedSymbolDeclaration*>(currentSymbol);
             47                             currentAccessor=symbol->accessor;
             48                         }
             49                         break;
             50                     case ManagedSymbolItem::TypeRename:
             51                         {
             52                             ManagedSymbolTypeRename* symbol=dynamic_cast<ManagedSymbolTypeRename*>(currentSymbol);
             53                             currentAccessor=symbol->accessor;
             54                         }
             55                         break;
             56                     case ManagedSymbolItem::GenericParameter:
             57                         break;
             58                     default:
             59                         argument.errors.Add(ManagedLanguageCodeException::GetTypeInvisible(languageElement, currentType));
             60                         return;
             61                     }
             62 
             63                     if(!parentType)
             64                     {
             65                         ManagedSymbolItem* parentSymbol=currentSymbol->GetParentItem();
             66                         switch(parentSymbol->GetSymbolType())
             67                         {
             68                         case ManagedSymbolItem::Class:
             69                         case ManagedSymbolItem::Structure:
             70                         case ManagedSymbolItem::Interface:
             71                             {
             72                                 ManagedSymbolDeclaration* parentDeclaration=dynamic_cast<ManagedSymbolDeclaration*>(parentSymbol);
             73                                 parentType=argument.symbolManager->GetThisType(parentDeclaration);
             74                             }
             75                             break;
             76                         }
             77                     }
             78                     if(parentType && !thisTypes.Contains(parentType))
             79                     {
             80                         if(baseTypes.Contains(parentType))
             81                         {
             82                             switch(currentAccessor)
             83                             {
             84                             case declatt::Public:
             85                             case declatt::Protected:
             86                             case declatt::Internal:
             87                             case declatt::ProtectedInternal:
             88                                 break;
             89                             default:
             90                                 argument.errors.Add(ManagedLanguageCodeException::GetTypeInvisible(languageElement, currentType));
             91                                 return;
             92                             }
             93                         }
             94                         else
             95                         {
             96                             switch(currentAccessor)
             97                             {
             98                             case declatt::Public:
             99                             case declatt::Internal:
            100                             case declatt::ProtectedInternal:
            101                                 break;
            102                             default:
            103                                 argument.errors.Add(ManagedLanguageCodeException::GetTypeInvisible(languageElement, currentType));
            104                                 return;
            105                             }
            106                         }
            107                     }
            108 
            109                     if(currentSymbol->GetSymbolType()==ManagedSymbolItem::TypeRename)
            110                     {
            111                         ManagedSymbolTypeRename* symbol=dynamic_cast<ManagedSymbolTypeRename*>(currentSymbol);
            112                         if(currentType->GetGenericDeclaration())
            113                         {
            114                             Dictionary<ManagedTypeSymbol*, ManagedTypeSymbol*> replacement;
            115                             for(vint i=0;i<symbol->orderedGenericParameterNames.Count();i++)
            116                             {
            117                                 ManagedTypeSymbol* key=argument.symbolManager->GetType(symbol->ItemGroup(symbol->orderedGenericParameterNames[i])->Items()[0]);
            118                                 ManagedTypeSymbol* value=currentType->GetGenericArguments()[i];
            119                                 replacement.Add(key, value);
            120                             }
            121                             parentType=argument.symbolManager->ReplaceGenericArguments(currentType, replacement.Wrap());
            122                         }
            123                         else
            124                         {
            125                             parentType=symbol->type;
            126                         }
            127                     }
            128                     else
            129                     {
            130                         parentType=currentType;
            131                     }
            132                 }
            133             }
            134 
            135             void CollectBaseTypes(ManagedTypeSymbol* thisType, List<ManagedTypeSymbol*>& baseTypes, const MAP& argument)
            136             {
            137                 vint oldCount=baseTypes.Count();
            138                 if(thisType->GetGenericDeclaration())
            139                 {
            140                     ManagedSymbolDeclaration* symbol=dynamic_cast<ManagedSymbolDeclaration*>(thisType->GetGenericDeclaration()->GetSymbol());
            141 
            142                     Dictionary<ManagedTypeSymbol*, ManagedTypeSymbol*> replacement;
            143                     for(vint i=0;i<symbol->orderedGenericParameterNames.Count();i++)
            144                     {
            145                         ManagedTypeSymbol* key=argument.symbolManager->GetType(symbol->ItemGroup(symbol->orderedGenericParameterNames[i])->Items()[0]);
            146                         ManagedTypeSymbol* value=thisType->GetGenericArguments()[i];
            147                         replacement.Add(key, value);
            148                     }
            149 
            150                     FOREACH(ManagedTypeSymbol*, baseType, symbol->baseTypes.Wrap())
            151                     {
            152                         ManagedTypeSymbol* translatedBaseType=argument.symbolManager->ReplaceGenericArguments(baseType, replacement.Wrap());
            153                         if(!baseTypes.Contains(translatedBaseType))
            154                         {
            155                             baseTypes.Add(translatedBaseType);
            156                         }
            157                     }
            158                 }
            159                 else
            160                 {
            161                     ManagedSymbolDeclaration* symbol=dynamic_cast<ManagedSymbolDeclaration*>(thisType->GetSymbol());
            162                     FOREACH(ManagedTypeSymbol*, baseType, symbol->baseTypes.Wrap())
            163                     {
            164                         if(!baseTypes.Contains(baseType))
            165                         {
            166                             baseTypes.Add(baseType);
            167                         }
            168                     }
            169                 }
            170                 for(vint i=oldCount;i<baseTypes.Count();i++)
            171                 {
            172                     CollectBaseTypes(baseTypes[i], baseTypes, argument);
            173                 }
            174             }
            175 
            176             void EnsureTypeVisibility(ManagedLanguageElement* languageElement, ManagedTypeSymbol* type, ManagedSymbolItem* scopeItem, const MAP& argument)
            177             {
            178                 CHECK_ERROR(
            179                     !scopeItem
            180                     || scopeItem->GetSymbolType()==ManagedSymbolItem::Class
            181                     || scopeItem->GetSymbolType()==ManagedSymbolItem::Structure
            182                     || scopeItem->GetSymbolType()==ManagedSymbolItem::Interface,
            183                     L"EnsureTypeVisibility(ManagedLanguageElement*, ManagedTypeSymbol*, ManagedSymbolItem*, const MAP&)#scopeItem內容非法。"
            184                     );
            185 
            186                 List<ManagedTypeSymbol*> thisTypes, baseTypes;
            187                 {
            188                     ManagedSymbolDeclaration* currentDeclaration=dynamic_cast<ManagedSymbolDeclaration*>(scopeItem);
            189                     while(currentDeclaration)
            190                     {
            191                         thisTypes.Add(argument.symbolManager->GetThisType(currentDeclaration));
            192                         currentDeclaration=dynamic_cast<ManagedSymbolDeclaration*>(currentDeclaration->GetParentItem());
            193                     }
            194                 }
            195                 FOREACH(ManagedTypeSymbol*, thisType, thisTypes.Wrap())
            196                 {
            197                     CollectBaseTypes(thisType, baseTypes, argument);
            198                 }
            199                 EnsureTypeVisibility(languageElement, type, argument, thisTypes, baseTypes);
            200             }

                主要方法就是,判斷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=xxx這條聲明的語義分析里面已經查過了,如果不可見就會有錯誤信息產生。因此這里可以當B<int, string>是可見的,減少多余的錯誤信息。

                然后判斷A<int>.S<string>是否可見比較簡單,主要就是判斷A<int>.S和string是否可見。

                一直這么遞歸下去,就把整個類型都檢查完了。

            posted on 2011-07-16 01:38 陳梓瀚(vczh) 閱讀(2844) 評論(1)  編輯 收藏 引用 所屬分類: VL++3.0開發紀事

            評論:
            # re: Vczh Library++3.0之ManagedX語言檢查類型的可見性 2011-07-16 06:30 | Ooseven
            加油!  回復  更多評論
              
            狠狠色丁香久久婷婷综| 亚洲精品乱码久久久久久蜜桃图片| 国产精品美女久久福利网站| 国产精品美女久久久久av爽 | 超级碰久久免费公开视频| 99久久精品免费看国产一区二区三区 | 亚洲色婷婷综合久久| 亚洲AV伊人久久青青草原| 久久综合给合综合久久| 精品人妻伦九区久久AAA片69| 大美女久久久久久j久久| 狠狠色伊人久久精品综合网| 伊人久久精品线影院| 国产香蕉97碰碰久久人人| 欧美伊人久久大香线蕉综合69| 久久这里有精品视频| 久久久久免费精品国产| 久久精品国产亚洲av影院| 久久超乳爆乳中文字幕| 久久久久一区二区三区| 狠狠久久综合伊人不卡| 久久乐国产综合亚洲精品| 久久香蕉超碰97国产精品| 91久久精品国产91性色也| 色综合久久久久综合99| 色欲久久久天天天综合网精品 | 国产精品免费久久| 欧美一区二区久久精品| 精品久久久噜噜噜久久久 | 日韩欧美亚洲国产精品字幕久久久| 亚洲国产成人久久笫一页| 色88久久久久高潮综合影院| 93精91精品国产综合久久香蕉| 久久这里的只有是精品23| 香港aa三级久久三级| 精品国产乱码久久久久久人妻| 97久久精品人人做人人爽| 久久综合噜噜激激的五月天| 99久久精品国产一区二区三区 | 99久久99久久精品国产| 无码人妻精品一区二区三区久久 |