Changeset 728 in dev for trunk/ab5.0


Ignore:
Timestamp:
Aug 21, 2008, 11:02:07 PM (16 years ago)
Author:
dai
Message:

#200への対応。ジェネリックインターフェイスを実装したジェネリッククラスのテンプレート展開に対応。

Location:
trunk/ab5.0/abdev
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/abdev/BasicCompiler_Common/include/LexicalAnalyzer.h

    r726 r728  
    3535    static Member *CreateMember( const CClass &_class, Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine );
    3636    static void AddMethod(CClass *pobj_c, UserProc *pUserProc, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
    37         bool isVirtual, bool isOverride, const char *interfaceName, bool isAutoGeneration, int nowLine);
     37        bool isVirtual, bool isOverride, bool isEnableOverrideCheck, const char *interfaceName, bool isAutoGeneration, int nowLine);
    3838    static bool Inherits( CClass &_class, const char *inheritNames, int nowLine );
    39     static void Implements( CClass &_class, Interface *pInterface, std::vector<DynamicMethod::OverrideResult> &overrideResults );
     39    static void Implements( CClass &_class, Interface *pInterface );
    4040    static bool Implements( CClass &_class, const char *interfaceNames, int nowLine );
    4141    static void LookaheadClass( const std::string &className, Classes &classes );
     
    4444
    4545    // テンプレート展開
     46    static Type LexicalAnalyzer::TemplateExpand_ResolveType( const Type &baseType, const Types &actualTypes );
    4647    static void TemplateExpand_ResolveMethod( const CMethod *pBaseMethod, const Types &actualTypes, CClass *pNewClass );
    4748    static const CClass *TemplateExpand( CClass &_class, const Types &actualTypes );
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Class.cpp

    r726 r728  
    278278
    279279void LexicalAnalyzer::AddMethod(CClass *pobj_c, UserProc *pUserProc, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
    280     bool isVirtual, bool isOverride, const char *interfaceName, bool isAutoGeneration, int nowLine)
     280    bool isVirtual, bool isOverride, bool isEnableOverrideCheck, const char *interfaceName, bool isAutoGeneration, int nowLine)
    281281{
    282282    if( isAutoGeneration )
     
    353353    {
    354354        DynamicMethod::OverrideResult result;
    355         result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isOverride );
     355        result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isEnableOverrideCheck ? isOverride : true );
    356356        result.pMethod = pMethodForOverride;
    357357        OverrideErrorCheck( result );
     
    514514}
    515515
    516 void LexicalAnalyzer::Implements( CClass &_class, Interface *pInterface, std::vector<DynamicMethod::OverrideResult> &overrideResults )
     516void LexicalAnalyzer::Implements( CClass &_class, Interface *pInterface )
    517517{
     518    // まずは継承されたインターフェイスを実装する
     519    BOOST_FOREACH( ::Interface *pInheritsInterface, pInterface->GetClass().GetInterfaces() )
     520    {
     521        // TODO: actualTypeParametersの引渡し
     522        Implements(
     523            _class,
     524            new ::Interface( &pInheritsInterface->GetClass(), pInterface->GetActualTypeParameters() )
     525        );
     526    }
     527
    518528    _class.AddInterface( pInterface );
    519529
     
    530540            result.enumType = pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
    531541            result.pMethod = pMethod;
    532             overrideResults.push_back( result );
     542
     543            OverrideErrorCheck( result );
    533544
    534545            // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
     
    588599            false,          // isVirtual
    589600            false,          // isOverride
     601            true,           // Override修飾子チェック
    590602            "",
    591603            true,           // isAutoGeneration
     
    633645        if( pInterfaceClass->IsInterface() || pInterfaceClass->IsComInterface() )
    634646        {
    635             // インターフェイスを継承する
    636             std::vector<DynamicMethod::OverrideResult> overrideResults;
    637             Implements(
    638                 _class,
    639                 new ::Interface( pInterfaceClass, actualTypeParameters ),
    640                 overrideResults
    641             );
    642 
    643             // エラーチェック
    644             BOOST_FOREACH( const DynamicMethod::OverrideResult result, overrideResults )
    645             {
    646                 OverrideErrorCheck( result );
     647            // インターフェイスを実装する
     648            {
     649                Implements(
     650                    _class,
     651                    new ::Interface( pInterfaceClass, actualTypeParameters )
     652                );
    647653            }
    648654        }
     
    844850
    845851                //継承させる
    846                 if( !pobj_c->InheritsClass( *pInheritsClass, actualTypeParameters, i ) ){
     852                if( !pobj_c->InheritsInterface( *pInheritsClass, actualTypeParameters, i ) ){
    847853                    goto Interface_InheritsError;
    848854                }
     
    934940                        true,               // isVirtual
    935941                        false,              // isOverride
     942                        true,               // Override修飾子チェック
    936943                        interfaceName,
    937944                        false,              // isAutoGeneration
     
    12701277                            isVirtual,
    12711278                            isOverride,
     1279                            true,               // Override修飾子チェック
    12721280                            interfaceName,
    12731281                            false,
     
    13451353}
    13461354
     1355Type LexicalAnalyzer::TemplateExpand_ResolveType( const Type &baseType, const Types &actualTypes )
     1356{
     1357    if( baseType.IsNull() )
     1358    {
     1359        return baseType;
     1360    }
     1361
     1362    Type resultType( baseType );
     1363    if( resultType.IsTypeParameter() )
     1364    {
     1365        // 型パラメータだったとき
     1366        resultType = actualTypes[baseType.GetFormalTypeIndex()];
     1367    }
     1368    else if( resultType.IsObject() || resultType.IsInterface() )
     1369    {
     1370        // クラス・インターフェイスだったとき
     1371        const CClass *pExpandedClass = TemplateExpand( *const_cast<CClass *>(&baseType.GetClass()), actualTypes );
     1372        resultType.SetClassPtr( pExpandedClass );
     1373    }
     1374
     1375    resultType.SetPtrLevel( baseType.PtrLevel() );
     1376
     1377    return resultType;
     1378}
     1379
    13471380void LexicalAnalyzer::TemplateExpand_ResolveMethod( const CMethod *pBaseMethod, const Types &actualTypes, CClass *pNewClass )
    13481381{
     
    13761409
    13771410    // 戻り値のジェネリック型を解決
    1378     if( pUserProc->ReturnType().IsTypeParameter() )
    1379     {
    1380         Type type = actualTypes[pUserProc->ReturnType().GetFormalTypeIndex()];
    1381         type.SetPtrLevel( pUserProc->ReturnType().PtrLevel() );
    1382         pUserProc->SetReturnType( type );
    1383     }
     1411    pUserProc->SetReturnType( TemplateExpand_ResolveType( pUserProc->ReturnType(), actualTypes ) );
    13841412
    13851413    compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
     
    13941422        pBaseMethod->IsAbstract(),
    13951423        pBaseMethod->IsVirtual(),
    1396         false,
     1424        false,                      // isOverride
     1425        false,                      // Override修飾子チェック
    13971426        "",
    13981427        false,
     
    14031432const CClass *LexicalAnalyzer::TemplateExpand( CClass &_class, const Types &actualTypes )
    14041433{
     1434    // そもそもジェネリック型ではないとき
     1435    if( !_class.IsGeneric() )
     1436    {
     1437        return &_class;
     1438    }
     1439
    14051440    // 展開済みのクラスがあればそれを返す
    14061441    BOOST_FOREACH( const ExpandedTemplateClass *pExpandedTemplateClass, _class.expandedTemplateClasses )
     
    14311466    );
    14321467
     1468    // 展開済みクラスとして登録
     1469    _class.expandedTemplateClasses.push_back( new ExpandedTemplateClass( pNewClass, actualTypes ) );
     1470
    14331471    // 基底クラス
    1434     pNewClass->SetSuperClass( &_class.GetSuperClass() );
     1472    if( _class.HasSuperClass() )
     1473    {
     1474        const CClass *pExpandedSuperClass = TemplateExpand( *const_cast<CClass *>(&_class.GetSuperClass()), actualTypes );
     1475        pNewClass->InheritsClass( *pExpandedSuperClass, pNewClass->GetSuperClassActualTypeParameters(), -1 );
     1476    }
    14351477
    14361478    // インターフェイスのジェネリック型を解決
    14371479    BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() )
    14381480    {
    1439         pNewClass->AddInterface( new ::Interface( &pInterface->GetClass(), actualTypes ) );
     1481        const CClass *pExpandedInterfaceClass = TemplateExpand( *const_cast<CClass *>(&pInterface->GetClass()), actualTypes );
     1482        Interface *pExpandedInterface = new ::Interface( pExpandedInterfaceClass, actualTypes );
     1483        pNewClass->AddInterface( pExpandedInterface );
     1484
     1485        // インターフェイス メソッドのジェネリック型を解決
     1486        BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() )
     1487        {
     1488            if( pMethod->GetUserProc().GetParentClassPtr() == &_class )
     1489            {
     1490                // ターゲットクラス内で実装されるメソッドの場合
     1491                TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
     1492            }
     1493        }
     1494
     1495        /////////////////////////////////
     1496        // オーバーライドチェック
     1497        /////////////////////////////////
     1498        if( pExpandedInterface->GetDynamicMethods().size() != pInterface->GetDynamicMethods().size() )
     1499        {
     1500            Jenga::Throw( "インターフェイス メソッドのジェネリック型の解決に失敗している" );
     1501        }
     1502        else
     1503        {
     1504            for( int i=0; i<pInterface->GetDynamicMethods().size(); i++ )
     1505            {
     1506                if( pInterface->GetDynamicMethods()[i]->IsAbstract() != pExpandedInterface->GetDynamicMethods()[i]->IsAbstract() )
     1507                {
     1508                    Jenga::Throw( "テンプレート展開時のオーバーライドに失敗している … " + pInterface->GetDynamicMethods()[i]->GetUserProc().GetFullName() );
     1509                }
     1510            }
     1511        }
    14401512    }
    14411513
     
    14611533        if( pMethod->GetUserProc().GetParentClassPtr() == &_class )
    14621534        {
    1463             // ターゲットクラス内で実装されるメソッドの場合
    1464 
     1535            // ターゲットクラス内で実装されるメソッドの場合のみ(その他のメソッドはInheritsClassで継承されているはず)
    14651536            TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
    14661537        }
    1467         else
    1468         {
    1469             DynamicMethod *pNewDynamicMethod = new DynamicMethod( *pMethod );
    1470             pNewClass->GetDynamicMethods().push_back( pNewDynamicMethod );
    1471         }
    1472     }
    1473 
    1474     // インターフェイス メソッドのジェネリック型を解決
    1475     BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() )
    1476     {
    1477         BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() )
    1478         {
    1479             TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
    1480         }
    14811538    }
    14821539
    14831540    pNewClass->SetVtblNum( _class.GetVtblNum() );
    1484 
    1485     // 展開済みクラスとして登録
    1486     _class.expandedTemplateClasses.push_back( new ExpandedTemplateClass( pNewClass, actualTypes ) );
    14871541
    14881542    pNewClass->Readed();
  • trunk/ab5.0/abdev/ab_common/include/Lexical/Class.h

    r672 r728  
    319319    bool InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine );
    320320
     321    // インターフェイス継承
     322    bool InheritsInterface( const CClass &inheritsInterfaceClass, const Types &actualTypeParameters, int nowLine );
     323
    321324    //メンバ、メソッドの追加
    322325    void AddDynamicMember( Member *pMember );
  • trunk/ab5.0/abdev/ab_common/include/Lexical/Interface.h

    r640 r728  
    6969    }
    7070    Interface()
     71        : pInterfaceClass( NULL )
     72        , vtblOffset( NULL )
    7173    {
    7274    }
  • trunk/ab5.0/abdev/ab_common/src/Lexical/Class.cpp

    r672 r728  
    110110
    111111    // 仮想関数になるメソッドに使用チェックをつける
    112     const CClass &objThis = *this;
    113     BOOST_FOREACH( const CMethod *pMethod, objThis.GetDynamicMethods() )
     112    const CClass &_class = *this;
     113    BOOST_FOREACH( const CMethod *pMethod, _class.GetDynamicMethods() )
    114114    {
    115115        if( pMethod->IsVirtual() )
     
    118118        }
    119119    }
    120 }
    121 
     120
     121    // インターフェイスメソッドに使用チェックをつける
     122    BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() )
     123    {
     124        BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() )
     125        {
     126            pMethod->GetUserProc().Using();
     127        }
     128    }
     129}
    122130bool CClass::IsClass() const
    123131{
     
    268276
    269277    return true;
     278}
     279
     280bool CClass::InheritsInterface( const CClass &inheritsInterfaceClass, const Types &actualTypeParameters, int nowLine )
     281{
     282    if( !( this->IsInterface() || this->IsComInterface() ) )
     283    {
     284        Jenga::Throw( "非インターフェイスに対してCClass::InheritsInterfaceメソッドが呼ばれた" );
     285    }
     286
     287    // インターフェイスを継承する
     288    return this->InheritsClass( inheritsInterfaceClass, actualTypeParameters, nowLine );
    270289}
    271290
  • trunk/ab5.0/abdev/compiler_x86/Compile_Object.cpp

    r702 r728  
    108108    int typeSize = pClass->GetSize();
    109109
    110     if(pClass->IsAbstract()){
     110    if(pClass->IsAbstract())
     111    {
     112        std::string tempMessage;
     113        BOOST_FOREACH( const CMethod *pMethod, pClass->GetDynamicMethods() ){
     114            if(pMethod->IsVirtual()){
     115                if(pMethod->IsAbstract()){
     116                    if( !tempMessage.empty() )
     117                    {
     118                        tempMessage += ", ";
     119                    }
     120                    tempMessage += pMethod->GetUserProc().GetName();
     121                }
     122            }
     123        }
     124
     125        // インターフェイスのvtbl
     126        BOOST_FOREACH( const ::Interface *pInterface, pClass->GetInterfaces() )
     127        {
     128            BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ){
     129                if(pMethod->IsVirtual()){
     130                    if(pMethod->IsAbstract()){
     131                        if( !tempMessage.empty() )
     132                        {
     133                            tempMessage += ", ";
     134                        }
     135                        tempMessage += pMethod->GetUserProc().GetName();
     136                    }
     137                }
     138            }
     139        }
     140
    111141        //抽象クラスだったとき
    112         compiler.errorMessenger.Output(125,pClass->GetName(),cp);
     142        compiler.errorMessenger.Output(-1,"\"%s\" は抽象クラスです。インスタンス化することはできません(抽象メソッド … " + tempMessage + ")。",cp);
    113143    }
    114144
  • trunk/ab5.0/abdev/compiler_x86/Compile_ProcOp.cpp

    r710 r728  
    250250        sprintf( temporary,
    251251            "Return New %s(ObjPtr( This ),Get_LONG_PTR( (Get_LONG_PTR( ObjPtr(This)+SizeOf(VoidPtr) ) + SizeOf(LONG_PTR)*%d) As VoidPtr ) As VoidPtr )",
    252             userProc.ReturnType().GetClass().GetFullName().c_str(),
     252            compiler.TypeToString( userProc.ReturnType() ).c_str(),
    253253            vtblMasterListIndex
    254254        );
Note: See TracChangeset for help on using the changeset viewer.