source: dev/branches/egtra/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Class.cpp

Last change on this file was 814, checked in by イグトランス (egtra), 14 years ago

LexicalAnalyzer周りの修正

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