source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Class.cpp@ 804

Last change on this file since 804 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 41.2 KB
Line 
1#include "stdafx.h"
2
3#include "../common.h"
4#ifdef _AMD64_
5#include "../../compiler_x64/opcode.h"
6#else
7#include "../../compiler_x86/opcode.h"
8#endif
9
10#include <hash_set>
11
12using namespace ActiveBasic::Compiler;
13
14
15void LexicalAnalyzer::CollectClassesForNameOnly( const char *source, Classes &classes )
16{
17 int i, i2;
18 char temporary[VN_SIZE];
19
20 // 名前空間管理
21 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
22 namespaceScopes.clear();
23
24 // Imports情報のクリア
25 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
26
27 for(i=0;;i++){
28 if(source[i]=='\0') break;
29
30 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
31 for(i+=2,i2=0;;i2++,i++){
32 if( IsCommandDelimitation( source[i] ) ){
33 temporary[i2]=0;
34 break;
35 }
36 temporary[i2]=source[i];
37 }
38 namespaceScopes.push_back( temporary );
39
40 continue;
41 }
42 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
43 if( namespaceScopes.size() <= 0 ){
44 compiler.errorMessenger.Output(12, "End Namespace", i );
45 }
46 else{
47 namespaceScopes.pop_back();
48 }
49
50 i += 2;
51 continue;
52 }
53 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
54 for(i+=2,i2=0;;i2++,i++){
55 if( IsCommandDelimitation( source[i] ) ){
56 temporary[i2]=0;
57 break;
58 }
59 temporary[i2]=source[i];
60 }
61 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
62 {
63 compiler.errorMessenger.Output(64,temporary,i );
64 }
65
66 continue;
67 }
68 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED )
69 {
70 // Imports情報のクリア
71 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
72 continue;
73 }
74
75 if(source[i]==1&&(
76 source[i+1]==ESC_CLASS||
77 source[i+1]==ESC_TYPE||
78 source[i+1]==ESC_INTERFACE
79 ))
80 {
81 int nowLine = i;
82 i += 2;
83
84 Type blittableType;
85 if(memicmp(source+i,"Align(",6)==0){
86 //アラインメント修飾子
87 i+=6;
88 i=JumpStringInPare(source,i)+1;
89 }
90 else if( memicmp( source + i, "Blittable(", 10 ) == 0 ){
91 // Blittable修飾子
92 i+=10;
93 i+=GetStringInPare_RemovePare(temporary,source+i)+1;
94 compiler.StringToType( temporary, blittableType );
95 }
96
97 bool isEnum = false;
98 bool isDelegate = false;
99 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
100 // 列挙型の場合
101 isEnum = true;
102
103 i += 2;
104 }
105 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
106 {
107 // デリゲートの場合
108 isDelegate = true;
109
110 i += 2;
111 }
112
113 for(i2=0;;i++,i2++){
114 if(!IsVariableChar(source[i])){
115 temporary[i2]=0;
116 break;
117 }
118 temporary[i2]=source[i];
119 }
120
121 //クラスを追加
122 CClass *pClass = new CClass( Symbol( namespaceScopes, temporary ), compiler.GetNamespaceSupporter().GetImportedNamespaces() );
123 if( classes.IsExist( pClass ) )
124 {
125 // 既に存在している
126 compiler.errorMessenger.Output(15,pClass->GetName(), nowLine);
127
128 delete pClass;
129
130 continue;
131 }
132
133 classes.Put( pClass );
134
135 if( source[nowLine+1] == ESC_CLASS )
136 {
137 if( isEnum )
138 {
139 pClass->SetClassType( CClass::Enum );
140 }
141 else if( isDelegate )
142 {
143 pClass->SetClassType( CClass::Delegate );
144 }
145 else{
146 pClass->SetClassType( CClass::Class );
147 }
148 }
149 else if( source[nowLine+1] == ESC_INTERFACE )
150 {
151 pClass->SetClassType( CClass::Interface );
152 }
153 else
154 {
155 pClass->SetClassType( CClass::Structure );
156 }
157
158 // Blittable型の場合
159 if( !blittableType.IsNull() ){
160 pClass->SetBlittableType( blittableType );
161
162 // Blittable型として登録
163 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
164 }
165 }
166 }
167}
168
169
170class CLoopRefCheck{
171 stdext::hash_set<std::string> names;
172
173public:
174 CLoopRefCheck()
175 {
176 }
177 ~CLoopRefCheck()
178 {
179 }
180 void add(const std::string &lpszInheritsClass)
181 {
182 names.insert(lpszInheritsClass);
183 }
184 void del(const std::string &lpszInheritsClass)
185 {
186 names.erase(lpszInheritsClass);
187 }
188 bool check(const CClass &inheritsClass) const
189 {
190 //ループ継承チェック
191 return names.find(inheritsClass.GetName()) != names.end();
192 }
193private:
194 CLoopRefCheck(const CLoopRefCheck&);
195 CLoopRefCheck& operator =(const CLoopRefCheck&);
196};
197CLoopRefCheck *pobj_LoopRefCheck;
198
199bool MemberVar_LoopRefCheck(const CClass &objClass){
200 if( objClass.HasSuperClass() )
201 {
202 // 基底クラスをチェック
203 if( MemberVar_LoopRefCheck( objClass.GetSuperClass() ) == false )
204 {
205 return false;
206 }
207 }
208
209 bool result = true;
210 foreach( Member *pMember, objClass.GetDynamicMembers() ){
211 if(pMember->GetType().IsStruct()){
212 //循環参照でないかをチェック
213 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
214 extern int cp;
215 compiler.errorMessenger.Output(124,pMember->GetType().GetClass().GetName(),cp);
216 return false;
217 }
218
219 pobj_LoopRefCheck->add(objClass.GetName());
220
221 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
222 if( result )
223 {
224 result = tempResult;
225 }
226
227 pobj_LoopRefCheck->del(objClass.GetName());
228 }
229 }
230
231 return result;
232}
233
234void OverrideErrorCheck( const DynamicMethod::OverrideResult &result )
235{
236 switch( result.enumType )
237 {
238 case DynamicMethod::OverrideResult::Successful:
239 break;
240 case DynamicMethod::OverrideResult::NotVirtual:
241 compiler.errorMessenger.Output(136, result.pMethod->GetUserProc().GetName(), cp);
242 break;
243 case DynamicMethod::OverrideResult::NotUseOverrideModifier:
244 compiler.errorMessenger.Output(127, result.pMethod->GetUserProc().GetName(), cp);
245 break;
246 case DynamicMethod::OverrideResult::DifferentAccesibility:
247 compiler.errorMessenger.Output(128, result.pMethod->GetUserProc().GetName(), cp);
248 break;
249 default:
250 throw;
251 }
252}
253
254Member *LexicalAnalyzer::CreateMember( const CClass &_class, Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
255{
256 extern int cp;
257
258 //構文を解析
259 char VarName[VN_SIZE];
260 char initBuffer[VN_SIZE];
261 char lpszConstructParameter[VN_SIZE];
262 Subscripts subscripts;
263 Type type;
264 if( !GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter) )
265 {
266 return NULL;
267 }
268
269 //重複チェック
270 if( _class.DupliCheckAll( VarName ) ){
271 compiler.errorMessenger.Output(15,VarName,cp);
272 }
273
274 Member *pMember = new Member( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
275 pMember->source_code_address = nowLine;
276 return pMember;
277}
278
279void LexicalAnalyzer::AddMethod(CClass *pobj_c, UserProc *pUserProc, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
280 bool isVirtual, bool isOverride, bool isEnableOverrideCheck, const char *interfaceName, bool isAutoGeneration, int nowLine)
281{
282 if( isAutoGeneration )
283 {
284 // コード自動生成
285 pUserProc->ThisIsAutoGenerationProc();
286 }
287
288
289 ////////////////////////////////////////////////////////////
290 // コンストラクタ、デストラクタの場合の処理
291 ////////////////////////////////////////////////////////////
292 BOOL fConstructor=0,bDestructor=0;
293
294 if( pUserProc->GetName() == pobj_c->GetName() ){
295 //コンストラクタの場合
296
297 //標準コンストラクタ(引数なし)
298 if(pUserProc->Params().size()==0) fConstructor=1;
299
300 //強制的にConst修飾子をつける
301 isConst = true;
302 }
303 else if(pUserProc->GetName()[0]=='~'){
304 //デストラクタの場合はその名前が正しいかチェックを行う
305 if(lstrcmp(pUserProc->GetName().c_str()+1,pobj_c->GetName().c_str())!=0)
306 compiler.errorMessenger.Output(117,NULL,nowLine);
307 else
308 bDestructor=1;
309 }
310 if(fConstructor||bDestructor){
311 // コンストラクタ、デストラクタのアクセシビリティをチェック
312
313 //強制的にConst修飾子をつける
314 isConst = true;
315 }
316
317 if( fConstructor == 1 )
318 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
319 else if( bDestructor )
320 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
321
322
323
324 //////////////////
325 // 重複チェック
326 //////////////////
327
328 if(pobj_c->DupliCheckMember( pUserProc->GetName().c_str() )){
329 compiler.errorMessenger.Output(15,pUserProc->GetName(),nowLine);
330 return;
331 }
332
333 //メソッド
334 foreach( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
335 {
336 //基底クラスと重複する場合はオーバーライドを行う
337 if( pMethod->GetInheritsClassPtr() ) continue;
338
339 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
340 {
341 //関数名、パラメータ、戻り値が合致したとき
342 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
343 return;
344 }
345 }
346
347 //仮想関数の場合
348 if( isAbstract ) pUserProc->CompleteCompile();
349
350 // メソッドのオーバーライド
351 DynamicMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
352 if( pMethodForOverride )
353 {
354 DynamicMethod::OverrideResult result;
355 result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isEnableOverrideCheck ? isOverride : true );
356 result.pMethod = pMethodForOverride;
357 OverrideErrorCheck( result );
358
359 pUserProc->SetMethod( pMethodForOverride );
360 return;
361 }
362 else
363 {
364 // インターフェイス メソッドのオーバーライド
365 foreach( ::Interface *pInterface, pobj_c->GetInterfaces() )
366 {
367 if( interfaceName[0] )
368 {
369 if( pInterface->GetClass().GetName() != interfaceName )
370 {
371 // 指定されたインターフェイス名と整合しないとき
372 continue;
373 }
374 }
375
376 if( !pInterface->GetClass().IsReady() ){
377 // インターフェイスが未解析のとき
378 LexicalAnalyzer::LookaheadClass(
379 pInterface->GetClass().GetName(),
380 compiler.GetObjectModule().meta.GetClasses()
381 );
382 }
383
384 DynamicMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
385 if( pMethodForOverride )
386 {
387 DynamicMethod::OverrideResult result;
388 result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isOverride );
389 result.pMethod = pMethodForOverride;
390 OverrideErrorCheck( result );
391
392 pUserProc->SetMethod( pMethodForOverride );
393 return;
394 }
395 }
396 }
397
398 if( interfaceName[0] )
399 {
400 compiler.errorMessenger.Output(139,interfaceName,nowLine);
401 }
402
403 if( isVirtual ){
404 pobj_c->AddVtblNum( 1 );
405 }
406
407 if( isOverride ){
408 compiler.errorMessenger.Output(12,"Override",nowLine);
409 }
410
411 if(bStatic){
412 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
413 }
414 else{
415 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
416 }
417}
418
419bool LexicalAnalyzer::Inherits( CClass &_class, const char *inheritNames, int nowLine ){
420 int i = 0;
421 bool isInheritsClass = false;
422 while( true ){
423
424 char temporary[VN_SIZE];
425 for( int i2=0;; i++, i2++ ){
426 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
427 temporary[i2] = 0;
428 break;
429 }
430 temporary[i2] = inheritNames[i];
431 }
432
433 // ジェネリクス構文を分解
434 char className[VN_SIZE];
435 Jenga::Common::Strings typeParameterStrings;
436 SplitGenericClassInstance( temporary, className, typeParameterStrings );
437
438 // 型パラメータ文字列から型データを取得
439 Types actualTypeParameters;
440 foreach( const std::string &typeParameterStr, typeParameterStrings )
441 {
442 Type type;
443 compiler.StringToType( typeParameterStr, type );
444 actualTypeParameters.push_back( type );
445 }
446
447 //継承元クラスを取得
448 const CClass *pInheritsClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef(
449 LexicalAnalyzer::FullNameToSymbol( className )
450 );
451 if( !pInheritsClass ){
452 compiler.errorMessenger.Output(106,className,nowLine);
453 return false;
454 }
455
456 if( pInheritsClass->IsClass() ){
457 // クラスを継承する
458 isInheritsClass = true;
459
460 //ループ継承でないかをチェック
461 if( !LexicalAnalyzer::LoopRefCheck(*pInheritsClass) )
462 {
463 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),nowLine);
464 return false;
465 }
466
467 if( !pInheritsClass->IsReady() ){
468 //継承先が読み取られていないとき
469 LexicalAnalyzer::LookaheadClass(
470 pInheritsClass->GetName(),
471 compiler.GetObjectModule().meta.GetClasses()
472 );
473 }
474
475 if( !_class.InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
476 return false;
477 }
478 }
479 else{
480 compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine);
481 return false;
482 }
483
484 if( inheritNames[i] == '\0' ){
485 break;
486 }
487 i++;
488 }
489
490 if( !isInheritsClass ){
491 const CClass *pObjectClass = compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
492 //ループ継承でないかをチェック
493 if( !LexicalAnalyzer::LoopRefCheck( *pObjectClass ) )
494 {
495 compiler.errorMessenger.Output(123,pObjectClass->GetName(),nowLine);
496 return false;
497 }
498
499 if( !pObjectClass->IsReady() ){
500 //継承先が読み取られていないとき
501 LexicalAnalyzer::LookaheadClass(
502 pObjectClass->GetName(),
503 compiler.GetObjectModule().meta.GetClasses()
504 );
505 }
506
507 // クラスを一つも継承していないとき
508 if( !_class.InheritsClass( *pObjectClass, Types(), nowLine ) ){
509 return false;
510 }
511 }
512
513 return true;
514}
515
516void LexicalAnalyzer::Implements( CClass &_class, Interface *pInterface )
517{
518 // まずは継承されたインターフェイスを実装する
519 foreach( ::Interface *pInheritsInterface, pInterface->GetClass().GetInterfaces() )
520 {
521 // TODO: actualTypeParametersの引渡し
522 Implements(
523 _class,
524 new ::Interface( &pInheritsInterface->GetClass(), pInterface->GetActualTypeParameters() )
525 );
526 }
527
528 _class.AddInterface( pInterface );
529
530
531 /////////////////////////////////////////////////////////////////
532 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
533 /////////////////////////////////////////////////////////////////
534 foreach( CMethod *pMethod, _class.GetDynamicMethods() )
535 {
536 DynamicMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), &pMethod->GetUserProc() );
537 if( pMethodForOverride )
538 {
539 DynamicMethod::OverrideResult result;
540 result.enumType = pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
541 result.pMethod = pMethod;
542
543 OverrideErrorCheck( result );
544
545 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
546 pMethod->SetNotUseMark( true );
547 }
548 }
549
550
551 /////////////////////////////////////////////////////////////////
552 // キャストメソッドを追加(内部コードは自動生成すること)
553 // ※COMインターフェイスは除外すること
554 /////////////////////////////////////////////////////////////////
555 if( pInterface->GetClass().IsInterface() )
556 {
557 // Function Operator() As ITest
558
559 char methodName[255] = { 1, ESC_OPERATOR, CALC_AS, '\0' };
560
561 //関数ハッシュへ登録
562 UserProc *pUserProc = new UserProc(
563 Symbol( NamespaceScopes(), methodName ),
564 NamespaceScopesCollection(),
565 Procedure::Function,
566 false,
567 false,
568 false );
569 pUserProc->SetParentClass( &_class );
570
571 Parameters params;
572 params.push_back( new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
573 pUserProc->SetRealParams( params );
574
575 pUserProc->SetReturnType( Type( DEF_OBJECT, pInterface->GetClass() ) );
576 pUserProc->_paramStr = "";
577 pUserProc->Using();
578
579 // 関数を追加
580 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) )
581 {
582 // 既に存在している
583 compiler.errorMessenger.Output(15,pUserProc->GetName(),-1);
584
585 delete pUserProc;
586 }
587 else
588 {
589 compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
590 }
591
592 LexicalAnalyzer::AddMethod(
593 &_class,
594 pUserProc,
595 Prototype::Public,
596 0,
597 false, // isConst
598 false, // isAbstract
599 false, // isVirtual
600 false, // isOverride
601 true, // Override修飾子チェック
602 "",
603 true, // isAutoGeneration
604 -1
605 );
606 }
607}
608
609bool LexicalAnalyzer::Implements( CClass &_class, const char *interfaceNames, int nowLine )
610{
611 Jenga::Common::Strings paramStrs;
612 SplitParameter( interfaceNames, paramStrs );
613
614 foreach( const std::string &paramStr, paramStrs )
615 {
616 char className[VN_SIZE];
617 Jenga::Common::Strings typeParameterStrings;
618 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
619
620 Types actualTypeParameters;
621 foreach( const std::string &typeParameterStr, typeParameterStrings )
622 {
623 Type type;
624 compiler.StringToType( typeParameterStr, type );
625 actualTypeParameters.push_back( type );
626 }
627
628 //継承元クラスを取得
629 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef(
630 LexicalAnalyzer::FullNameToSymbol( className )
631 );
632 if( !pInterfaceClass ){
633 compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine);
634 continue;
635 }
636
637 if( !pInterfaceClass->IsReady() ){
638 // インターフェイスが未解析のとき
639 LexicalAnalyzer::LookaheadClass(
640 pInterfaceClass->GetName(),
641 compiler.GetObjectModule().meta.GetClasses()
642 );
643 }
644
645 if( pInterfaceClass->IsInterface() || pInterfaceClass->IsComInterface() )
646 {
647 // インターフェイスを実装する
648 {
649 Implements(
650 _class,
651 new ::Interface( pInterfaceClass, actualTypeParameters )
652 );
653 }
654 }
655 else
656 {
657 // インターフェイスではないとき
658 compiler.errorMessenger.Output(138,pInterfaceClass->GetName().c_str(),nowLine );
659 }
660 }
661
662 return true;
663}
664
665void GetClass_recur( const char *lpszInheritsClass, Classes &classes )
666{
667 extern char *basbuf;
668 int i,i2,i3,sub_address,top_pos;
669 char temporary[8192];
670
671 // 名前空間管理
672 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
673 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
674 namespaceScopes.clear();
675
676 // Importsされた名前空間の管理
677 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
678 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
679
680 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
681 const CClass *pBackCompilingClass = compiler.IsCompilingClass()
682 ? &compiler.GetCompilingClass()
683 : NULL;
684
685 for(i=0;;i++){
686 if(basbuf[i]=='\0') break;
687
688
689 // 名前空間
690 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
691 for(i+=2,i2=0;;i2++,i++){
692 if( IsCommandDelimitation( basbuf[i] ) ){
693 temporary[i2]=0;
694 break;
695 }
696 temporary[i2]=basbuf[i];
697 }
698 namespaceScopes.push_back( temporary );
699
700 continue;
701 }
702 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
703 if( namespaceScopes.size() <= 0 ){
704 compiler.errorMessenger.Output(12, "End Namespace", i );
705 }
706 else{
707 namespaceScopes.pop_back();
708 }
709
710 i += 2;
711 continue;
712 }
713
714 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
715 for(i+=2,i2=0;;i2++,i++){
716 if( IsCommandDelimitation( basbuf[i] ) ){
717 temporary[i2]=0;
718 break;
719 }
720 temporary[i2]=basbuf[i];
721 }
722 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
723 {
724 compiler.errorMessenger.Output(64,temporary,i );
725 }
726
727 continue;
728 }
729 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED )
730 {
731 // Imports情報のクリア
732 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
733 continue;
734 }
735
736
737
738 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
739 //////////////////////////
740 // インターフェイス
741 //////////////////////////
742
743 top_pos=i;
744
745 i+=2;
746
747 //インターフェイス名を取得
748 GetCommandToken( temporary, basbuf, i );
749
750 char className[VN_SIZE];
751 Jenga::Common::Strings typeParameters;
752 Jenga::Common::Strings typeParameterBaseClassNames;
753 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
754
755 CClass *pobj_c = const_cast<CClass *>( classes.FindEx( Symbol( namespaceScopes, className ) ) );
756 if(!pobj_c) continue;
757
758 compiler.SetCompilingClass( pobj_c );
759
760 if(lpszInheritsClass){
761 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
762 //継承先先読み用
763 continue;
764 }
765 }
766
767 if(pobj_c->IsReady()){
768 //既に先読みされているとき
769 continue;
770 }
771
772 /////////////////////////////////////////////////////////
773 // ☆★☆ ジェネリクスサポート ☆★☆
774 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
775 {
776 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
777 if( typeParameterBaseClassNames[i2].size() )
778 {
779 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
780 {
781 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
782 }
783 else if( !baseType.IsObject() )
784 {
785 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
786 }
787 }
788
789 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
790 }
791 /////////////////////////////////////////////////////////
792
793 pobj_c->Readed();
794
795 pobj_c->SetConstructorMemberSubIndex( -1 );
796 pobj_c->SetDestructorMemberSubIndex( -1 );
797
798 if( memcmp( basbuf+i+1, "__COM", 5 ) == 0 && IsCommandDelimitation( basbuf[i+1+5] ) )
799 {
800 // COMインターフェイス
801 pobj_c->SetClassType( CClass::ComInterface );
802
803 i += 6;
804 }
805
806 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
807 //継承を行う場合
808 for(i+=3,i2=0;;i++,i2++){
809 if(IsCommandDelimitation(basbuf[i])){
810 temporary[i2]=0;
811 break;
812 }
813 temporary[i2]=basbuf[i];
814 }
815
816 // ジェネリクス構文を分解
817 char className[VN_SIZE];
818 Jenga::Common::Strings typeParameterStrings;
819 SplitGenericClassInstance( temporary, className, typeParameterStrings );
820
821 // 型パラメータ文字列から型データを取得
822 Types actualTypeParameters;
823 foreach( const std::string &typeParameterStr, typeParameterStrings )
824 {
825 Type type;
826 compiler.StringToType( typeParameterStr, type );
827 actualTypeParameters.push_back( type );
828 }
829
830 if(lstrcmpi(className,pobj_c->GetName().c_str())==0){
831 compiler.errorMessenger.Output(105,className,i);
832 goto Interface_InheritsError;
833 }
834
835 //継承元クラスを取得
836 const CClass *pInheritsClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef(
837 LexicalAnalyzer::FullNameToSymbol( className )
838 );
839 if( !pInheritsClass ){
840 compiler.errorMessenger.Output(106,className,i);
841 goto Interface_InheritsError;
842 }
843
844 //ループ継承でないかをチェック
845 if( !LexicalAnalyzer::LoopRefCheck( *pInheritsClass ) )
846 {
847 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),i);
848 goto Interface_InheritsError;
849 }
850
851 //継承させる
852 if( !pobj_c->InheritsInterface( *pInheritsClass, actualTypeParameters, i ) ){
853 goto Interface_InheritsError;
854 }
855 }
856 else{
857 //継承無し
858 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
859 {
860 // TODO: ここに来ないことが実証できたらこの分岐は消す
861 Jenga::Throw( "GetClass_recur内の例外" );
862 }
863 }
864Interface_InheritsError:
865
866 //メンバ変数、関数を取得
867 while(1){
868 i++;
869
870 //エラー
871 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
872 compiler.errorMessenger.Output(22,"Interface",i);
873 i--;
874 break;
875 }
876
877 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
878 compiler.errorMessenger.Output(111,NULL,i);
879 break;
880 }
881 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
882 {
883 compiler.errorMessenger.Output(137, NULL, i );
884 break;
885 }
886
887 sub_address=i;
888
889 for(i2=0;;i++,i2++){
890 if(IsCommandDelimitation(basbuf[i])){
891 temporary[i2]=0;
892 break;
893 }
894 temporary[i2]=basbuf[i];
895 }
896 if(temporary[0]=='\0'){
897 if(basbuf[i]=='\0'){
898 i--;
899 compiler.errorMessenger.Output(22,"Interface",top_pos);
900 break;
901 }
902 continue;
903 }
904
905 //End Interface記述の場合
906 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
907
908 if(!(temporary[0]==1&&(
909 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
910 ))){
911 compiler.errorMessenger.Output(1,NULL,i);
912 break;
913 }
914
915 //関数ハッシュへ登録
916 char interfaceName[VN_SIZE] = "";
917 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,true,pobj_c, false, interfaceName );
918 if( pUserProc )
919 {
920 // 関数を追加
921 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) )
922 {
923 // 既に存在している
924 compiler.errorMessenger.Output(15,pUserProc->GetName(),i);
925
926 delete pUserProc;
927 }
928 else
929 {
930 compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
931 }
932
933 //メンバ関数を追加
934 LexicalAnalyzer::AddMethod(pobj_c,
935 pUserProc,
936 Prototype::Public, //Publicアクセス権
937 0, // bStatic
938 false, // isConst
939 true, // isAbstract
940 true, // isVirtual
941 false, // isOverride
942 true, // Override修飾子チェック
943 interfaceName,
944 false, // isAutoGeneration
945 sub_address
946 );
947 }
948 }
949 }
950
951 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
952 //////////////////////////
953 // クラス
954 //////////////////////////
955
956 top_pos=i;
957
958 const DWORD dwClassType=basbuf[i+1];
959
960 i+=2;
961
962 int iAlign=0;
963 if(memicmp(basbuf+i,"Align(",6)==0){
964 //アラインメント修飾子
965 i+=6;
966 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
967 iAlign=atoi(temporary);
968
969 if( dwClassType != ESC_TYPE )
970 {
971 compiler.errorMessenger.Output(140,NULL,i);
972 }
973
974 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
975 compiler.errorMessenger.Output(51,NULL,i);
976 }
977 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
978 // Blittable修飾子
979 i+=10;
980 i=JumpStringInPare(basbuf,i)+1;
981
982 if( dwClassType != ESC_CLASS )
983 {
984 compiler.errorMessenger.Output(141,NULL,i);
985 }
986 }
987
988 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
989 {
990 // 列挙型の場合
991 i += 2;
992 }
993 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
994 {
995 // デリゲートの場合
996 i += 2;
997 }
998
999 //クラス名を取得
1000 GetCommandToken( temporary, basbuf, i );
1001
1002 char className[VN_SIZE];
1003 Jenga::Common::Strings typeParameters;
1004 Jenga::Common::Strings typeParameterBaseClassNames;
1005 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
1006
1007 CClass *pobj_c = const_cast<CClass *>( classes.FindEx( Symbol( namespaceScopes, className ) ) );
1008 if(!pobj_c) continue;
1009
1010 compiler.SetCompilingClass( pobj_c );
1011
1012 if(lpszInheritsClass){
1013 if( pobj_c->GetName() != lpszInheritsClass ){
1014 //継承先先読み用
1015 continue;
1016 }
1017 }
1018
1019 if(pobj_c->IsReady()){
1020 //既に先読みされているとき
1021 continue;
1022 }
1023
1024
1025 /////////////////////////////////////////////////////////
1026 // ☆★☆ ジェネリクスサポート ☆★☆
1027 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
1028 {
1029 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
1030 if( typeParameterBaseClassNames[i2].size() )
1031 {
1032 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
1033 {
1034 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
1035 }
1036 else if( !baseType.IsObject() )
1037 {
1038 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
1039 }
1040 }
1041
1042 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
1043 }
1044 /////////////////////////////////////////////////////////
1045
1046
1047 pobj_c->SetFixedAlignment( iAlign );
1048
1049 pobj_c->Readed();
1050
1051 pobj_c->SetConstructorMemberSubIndex( -1 );
1052 pobj_c->SetDestructorMemberSubIndex( -1 );
1053
1054 //アクセス制限の初期値をセット
1055 Prototype::Accessibility accessibility;
1056 if(dwClassType==ESC_CLASS){
1057 accessibility = Prototype::Private;
1058 }
1059 else{
1060 accessibility = Prototype::Public;
1061 }
1062
1063 if( pobj_c->GetName() == "Object"
1064 || dwClassType == ESC_TYPE )
1065 {
1066 // 何も継承しない
1067
1068 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1069 {
1070 // TODO: ここに来ないことが実証できたらこの分岐は消す
1071 Jenga::Throw( "GetClass_recur内の例外" );
1072 }
1073 }
1074 else{
1075 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS)
1076 {
1077 // クラス継承先が指定されているとき
1078 i += 3;
1079 GetCommandToken( temporary, basbuf, i );
1080
1081 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1082 compiler.errorMessenger.Output(105,temporary,i);
1083 goto InheritsError;
1084 }
1085 }
1086 else
1087 {
1088 // 何の指定もないときはObjectクラスを継承する
1089 lstrcpy( temporary, "Object" );
1090 }
1091 LexicalAnalyzer::Inherits( *pobj_c, temporary, i );
1092
1093 if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS )
1094 {
1095 // インターフェイス実装を行う場合
1096 i += 3;
1097 GetCommandToken( temporary, basbuf, i );
1098
1099 LexicalAnalyzer::Implements( *pobj_c, temporary, i );
1100 }
1101 }
1102InheritsError:
1103
1104 //メンバとメソッドを取得
1105 while(1){
1106 i++;
1107
1108 //エラー
1109 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1110 compiler.errorMessenger.Output(22,"Class",i);
1111 i--;
1112 break;
1113 }
1114
1115 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1116 compiler.errorMessenger.Output(111,NULL,i);
1117 break;
1118 }
1119 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
1120 {
1121 compiler.errorMessenger.Output(137, NULL, i );
1122 break;
1123 }
1124
1125 //Static修飾子
1126 BOOL bStatic;
1127 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1128 bStatic=1;
1129 i+=2;
1130 }
1131 else bStatic=0;
1132
1133 //Const修飾子
1134 bool isConst = false;
1135 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1136 isConst = true;
1137 i += 2;
1138 }
1139
1140 if(basbuf[i]==1&&(
1141 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1142 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1143 )){
1144 i3=basbuf[i+1];
1145 sub_address=i;
1146 }
1147 else i3=0;
1148
1149 bool isVirtual = false, isAbstract = false, isOverride = false;
1150 if(i3==ESC_ABSTRACT){
1151 isAbstract=1;
1152 isVirtual=1;
1153 i+=2;
1154
1155 i3=basbuf[i+1];
1156 }
1157 else if(i3==ESC_VIRTUAL){
1158 isAbstract=0;
1159 isVirtual=1;
1160 i+=2;
1161
1162 i3=basbuf[i+1];
1163 }
1164 else if(i3==ESC_OVERRIDE){
1165 isOverride=1;
1166 isVirtual=1;
1167
1168 i+=2;
1169
1170 i3=basbuf[i+1];
1171 }
1172
1173 for(i2=0;;i++,i2++){
1174 if(IsCommandDelimitation(basbuf[i])){
1175 temporary[i2]=0;
1176 break;
1177 }
1178 temporary[i2]=basbuf[i];
1179 }
1180 if(temporary[0]=='\0'){
1181 if(basbuf[i]=='\0'){
1182
1183 if(dwClassType==ESC_CLASS)
1184 compiler.errorMessenger.Output(22,"Class",top_pos);
1185 else
1186 compiler.errorMessenger.Output(22,"Type",top_pos);
1187
1188 i--;
1189 break;
1190 }
1191 continue;
1192 }
1193
1194 //End Class記述の場合
1195 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1196 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1197
1198 //アクセスを変更
1199 if(lstrcmpi(temporary,"Private")==0){
1200 accessibility = Prototype::Private;
1201 continue;
1202 }
1203 if(lstrcmpi(temporary,"Public")==0){
1204 accessibility = Prototype::Public;
1205 continue;
1206 }
1207 if(lstrcmpi(temporary,"Protected")==0){
1208 accessibility = Prototype::Protected;
1209 continue;
1210 }
1211
1212 extern int cp;
1213 if(i3==0){
1214 cp=i; //エラー用
1215 Member *pMember = LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i );
1216 if( pMember )
1217 {
1218 if(bStatic)
1219 {
1220 //静的メンバを追加
1221 pobj_c->AddStaticMember( pMember );
1222 }
1223 else
1224 {
1225 //メンバを追加
1226 pobj_c->AddDynamicMember( pMember );
1227
1228
1229 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
1230 if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
1231 //参照先が読み取られていないとき
1232 GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
1233 }
1234 }
1235
1236
1237 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
1238 //循環参照のチェック
1239 pobj_LoopRefCheck->add(pobj_c->GetName());
1240 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
1241 //エラー回避
1242 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
1243 type.SetBasicType( DEF_PTR_VOID );
1244 }
1245 pobj_LoopRefCheck->del(pobj_c->GetName());
1246 }
1247 }
1248 }
1249 }
1250 else{
1251 //関数ハッシュへ登録
1252 char interfaceName[VN_SIZE] = "";
1253 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,isVirtual,pobj_c, (bStatic!=0), interfaceName );
1254 if( pUserProc )
1255 {
1256 // 関数を追加
1257 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) )
1258 {
1259 // 既に存在している
1260 compiler.errorMessenger.Output(15,pUserProc->GetName(),i);
1261
1262 delete pUserProc;
1263 }
1264 else
1265 {
1266 compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
1267 }
1268
1269 //メソッドを追加
1270 cp=i; //エラー用
1271 LexicalAnalyzer::AddMethod(pobj_c,
1272 pUserProc,
1273 accessibility,
1274 bStatic,
1275 isConst,
1276 isAbstract,
1277 isVirtual,
1278 isOverride,
1279 true, // Override修飾子チェック
1280 interfaceName,
1281 false,
1282 sub_address);
1283 }
1284
1285 if( isAbstract ) continue;
1286
1287 for(;;i++){
1288 if(basbuf[i]=='\0'){
1289 i--;
1290 break;
1291 }
1292 if(basbuf[i-1]!='*'&&
1293 basbuf[i]==1&&(
1294 basbuf[i+1]==ESC_SUB||
1295 basbuf[i+1]==ESC_FUNCTION||
1296 basbuf[i+1]==ESC_MACRO||
1297 basbuf[i+1]==ESC_TYPE||
1298 basbuf[i+1]==ESC_CLASS||
1299 basbuf[i+1]==ESC_INTERFACE||
1300 basbuf[i+1]==ESC_ENUM)){
1301 GetDefaultNameFromES(i3,temporary);
1302 compiler.errorMessenger.Output(22,temporary,i);
1303 }
1304 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1305 i+=2;
1306 break;
1307 }
1308 }
1309 }
1310 }
1311 }
1312 }
1313
1314 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
1315 compiler.SetCompilingClass( pBackCompilingClass );
1316
1317 // 名前空間を元に戻す
1318 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1319
1320 // インポートされた名前空間を元に戻す
1321 compiler.GetNamespaceSupporter().SetImportedNamespaces( backupImportedNamespaces );
1322}
1323
1324void LexicalAnalyzer::LookaheadClass( const std::string &className, Classes &classes )
1325{
1326 pobj_LoopRefCheck->add( className );
1327 GetClass_recur( className.c_str(), classes );
1328 pobj_LoopRefCheck->del( className );
1329}
1330
1331bool LexicalAnalyzer::LoopRefCheck( const CClass &objClass )
1332{
1333 if( pobj_LoopRefCheck->check( objClass ) )
1334 {
1335 return false;
1336 }
1337
1338 return true;
1339}
1340
1341void LexicalAnalyzer::CollectClasses( const char *source, Classes &classes ){
1342 //ループ継承チェック用のクラス
1343 pobj_LoopRefCheck=new CLoopRefCheck();
1344
1345 //クラスを取得
1346 GetClass_recur( 0, classes );
1347
1348 delete pobj_LoopRefCheck;
1349 pobj_LoopRefCheck=0;
1350
1351 // イテレータの準備
1352 classes.Iterator_Init();
1353}
1354
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
1380void LexicalAnalyzer::TemplateExpand_ResolveMethod( const CMethod *pBaseMethod, const Types &actualTypes, CClass *pNewClass )
1381{
1382 UserProc *pUserProc = new UserProc(
1383 pBaseMethod->GetUserProc(),
1384 pNewClass
1385 );
1386 pUserProc->Using();
1387 pUserProc->GetParameters().clear();
1388 pUserProc->RealParams().clear();
1389
1390 // パラメータのジェネリック型を解決
1391 foreach( const Parameter *pParam, pBaseMethod->GetUserProc().Params() )
1392 {
1393 Type type = pParam->IsTypeParameter()
1394 ? actualTypes[pParam->GetFormalTypeIndex()]
1395 : *pParam;
1396 type.SetPtrLevel( pParam->PtrLevel() );
1397
1398 pUserProc->GetParameters().push_back( new Parameter( *pParam, type ) );
1399 }
1400 foreach( const Parameter *pParam, pBaseMethod->GetUserProc().RealParams() )
1401 {
1402 Type type = pParam->IsTypeParameter()
1403 ? actualTypes[pParam->GetFormalTypeIndex()]
1404 : *pParam;
1405 type.SetPtrLevel( pParam->PtrLevel() );
1406
1407 pUserProc->RealParams().push_back( new Parameter( *pParam, type ) );
1408 }
1409
1410 // 戻り値のジェネリック型を解決
1411 pUserProc->SetReturnType( TemplateExpand_ResolveType( pUserProc->ReturnType(), actualTypes ) );
1412
1413 compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
1414 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Init();
1415
1416 LexicalAnalyzer::AddMethod(
1417 pNewClass,
1418 pUserProc,
1419 pBaseMethod->GetAccessibility(),
1420 pBaseMethod->IsStatic(),
1421 pBaseMethod->IsConst(),
1422 pBaseMethod->IsAbstract(),
1423 pBaseMethod->IsVirtual(),
1424 false, // isOverride
1425 false, // Override修飾子チェック
1426 "",
1427 false,
1428 -1
1429 );
1430}
1431
1432const CClass *LexicalAnalyzer::TemplateExpand( CClass &_class, const Types &actualTypes )
1433{
1434 // そもそもジェネリック型ではないとき
1435 if( !_class.IsGeneric() )
1436 {
1437 return &_class;
1438 }
1439
1440 // 実型パラメータに値型が含まれないとき
1441 bool isValueType = false;
1442 foreach( const Type &actualType, actualTypes )
1443 {
1444 if( actualType.IsValueType() )
1445 {
1446 isValueType = true;
1447 }
1448 }
1449 if( !isValueType )
1450 {
1451 return &_class;
1452 }
1453
1454 // 展開済みのクラスがあればそれを返す
1455 foreach( const ExpandedTemplateClass *pExpandedTemplateClass, _class.expandedTemplateClasses )
1456 {
1457 if( pExpandedTemplateClass->GetActualTypes().IsEquals( actualTypes ) )
1458 {
1459 return &pExpandedTemplateClass->GetClass();
1460 }
1461 }
1462
1463
1464 /////////////////////////////////////////////////////////////////
1465 // 未展開の場合は新たに展開する
1466 /////////////////////////////////////////////////////////////////
1467
1468 // クラスをコピー
1469 CClass *pNewClass = new CClass(
1470 _class,
1471 _class.GetImportedNamespaces(),
1472 _class.GetClassType(),
1473 _class.GetFormalGenericTypes(),
1474 _class.GetSuperClassActualTypeParameters(),
1475 _class.GetConstructorMemberSubIndex(),
1476 _class.GetDestructorMemberSubIndex(),
1477 0,
1478 _class.GetFixedAlignment(),
1479 actualTypes
1480 );
1481
1482 // 展開済みクラスとして登録
1483 _class.expandedTemplateClasses.push_back( new ExpandedTemplateClass( pNewClass, actualTypes ) );
1484
1485 // 基底クラス
1486 if( _class.HasSuperClass() )
1487 {
1488 Types expandedSuperClassActualTypes;
1489 foreach( const Type &superClassActualType, _class.GetSuperClassActualTypeParameters() )
1490 {
1491 expandedSuperClassActualTypes.push_back( TemplateExpand_ResolveType( superClassActualType, actualTypes ) );
1492 }
1493
1494 const CClass *pExpandedSuperClass = TemplateExpand( *const_cast<CClass *>(&_class.GetSuperClass()), expandedSuperClassActualTypes );
1495 pNewClass->InheritsClass( *pExpandedSuperClass, expandedSuperClassActualTypes, -1 );
1496 }
1497
1498 // インターフェイスのジェネリック型を解決
1499 foreach( const ::Interface *pInterface, _class.GetInterfaces() )
1500 {
1501 const CClass *pExpandedInterfaceClass = TemplateExpand( *const_cast<CClass *>(&pInterface->GetClass()), actualTypes );
1502 Interface *pExpandedInterface = new ::Interface( pExpandedInterfaceClass, actualTypes );
1503 pNewClass->AddInterface( pExpandedInterface );
1504
1505 // インターフェイス メソッドのジェネリック型を解決
1506 foreach( const CMethod *pMethod, pInterface->GetDynamicMethods() )
1507 {
1508 if( pMethod->GetUserProc().GetParentClassPtr() == &_class )
1509 {
1510 // ターゲットクラス内で実装されるメソッドの場合
1511 TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
1512 }
1513 }
1514
1515 /////////////////////////////////
1516 // オーバーライドチェック
1517 /////////////////////////////////
1518 if( pExpandedInterface->GetDynamicMethods().size() != pInterface->GetDynamicMethods().size() )
1519 {
1520 Jenga::Throw( "インターフェイス メソッドのジェネリック型の解決に失敗している" );
1521 }
1522 else
1523 {
1524 for( int i=0; i<pInterface->GetDynamicMethods().size(); i++ )
1525 {
1526 if( pInterface->GetDynamicMethods()[i]->IsAbstract() != pExpandedInterface->GetDynamicMethods()[i]->IsAbstract() )
1527 {
1528 Jenga::Throw( "テンプレート展開時のオーバーライドに失敗している … " + pInterface->GetDynamicMethods()[i]->GetUserProc().GetFullName() );
1529 }
1530 }
1531 }
1532 }
1533
1534 // メンバのジェネリック型を解決
1535 foreach( const Member *pMember, _class.GetDynamicMembers() )
1536 {
1537 Type type = pMember->GetType();
1538 if( type.IsTypeParameter() )
1539 {
1540 // ジェネリック型だったときは値型に変換
1541 type = actualTypes[type.GetFormalTypeIndex()];
1542 type.SetPtrLevel( pMember->GetType().PtrLevel() );
1543 }
1544
1545 pNewClass->GetDynamicMembers().push_back(
1546 new Member( *pMember, type )
1547 );
1548 }
1549
1550 // クラス メソッドのジェネリック型を解決
1551 foreach( const CMethod *pMethod, _class.GetDynamicMethods() )
1552 {
1553 if( pMethod->GetUserProc().GetParentClassPtr() == &_class )
1554 {
1555 // ターゲットクラス内で実装されるメソッドの場合のみ(その他のメソッドはInheritsClassで継承されているはず)
1556 TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
1557 }
1558 }
1559
1560 pNewClass->SetVtblNum( _class.GetVtblNum() );
1561
1562 pNewClass->Readed();
1563
1564 return pNewClass;
1565}
Note: See TracBrowser for help on using the repository browser.