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

Last change on this file since 558 was 558, checked in by dai_9181, 16 years ago

Overrideメソッド内で発生したエラーのエラーメッセージ表示処理は呼び出し元で行うようにした。

File size: 30.7 KB
Line 
1#include "stdafx.h"
2
3#include <Source.h>
4#include <Class.h>
5#include <Compiler.h>
6
7#include "../common.h"
8#ifdef _AMD64_
9#include "../../compiler_x64/opcode.h"
10#else
11#include "../../compiler_x86/opcode.h"
12#endif
13
14using namespace ActiveBasic::Compiler;
15
16
17void LexicalAnalyzer::CollectClassesForNameOnly( const char *source, Classes &classes )
18{
19 int i, i2;
20 char temporary[VN_SIZE];
21
22 // 名前空間管理
23 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
24 namespaceScopes.clear();
25
26 // Importsされた名前空間の管理
27 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
28 importedNamespaces.clear();
29
30 for(i=0;;i++){
31 if(source[i]=='\0') break;
32
33 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
34 for(i+=2,i2=0;;i2++,i++){
35 if( IsCommandDelimitation( source[i] ) ){
36 temporary[i2]=0;
37 break;
38 }
39 temporary[i2]=source[i];
40 }
41 namespaceScopes.push_back( temporary );
42
43 continue;
44 }
45 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
46 if( namespaceScopes.size() <= 0 ){
47 compiler.errorMessenger.Output(12, "End Namespace", i );
48 }
49 else{
50 namespaceScopes.pop_back();
51 }
52
53 i += 2;
54 continue;
55 }
56 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
57 for(i+=2,i2=0;;i2++,i++){
58 if( IsCommandDelimitation( source[i] ) ){
59 temporary[i2]=0;
60 break;
61 }
62 temporary[i2]=source[i];
63 }
64 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
65 {
66 compiler.errorMessenger.Output(64,temporary,i );
67 }
68
69 continue;
70 }
71 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
72 importedNamespaces.clear();
73 continue;
74 }
75
76 if(source[i]==1&&(
77 source[i+1]==ESC_CLASS||
78 source[i+1]==ESC_TYPE||
79 source[i+1]==ESC_INTERFACE
80 ))
81 {
82 int nowLine = i;
83 i += 2;
84
85 Type blittableType;
86 if(memicmp(source+i,"Align(",6)==0){
87 //アラインメント修飾子
88 i+=6;
89 i=JumpStringInPare(source,i)+1;
90 }
91 else if( memicmp( source + i, "Blittable(", 10 ) == 0 ){
92 // Blittable修飾子
93 i+=10;
94 i+=GetStringInPare_RemovePare(temporary,source+i)+1;
95 compiler.StringToType( temporary, blittableType );
96 }
97
98 bool isEnum = false;
99 bool isDelegate = false;
100 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
101 // 列挙型の場合
102 isEnum = true;
103
104 i += 2;
105 }
106 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
107 {
108 // デリゲートの場合
109 isDelegate = true;
110
111 i += 2;
112 }
113
114 for(i2=0;;i++,i2++){
115 if(!IsVariableChar(source[i])){
116 temporary[i2]=0;
117 break;
118 }
119 temporary[i2]=source[i];
120 }
121
122 //クラスを追加
123 CClass *pClass = classes.Add(namespaceScopes, importedNamespaces, temporary,nowLine);
124 if( pClass ){
125 if( source[nowLine+1] == ESC_CLASS ){
126 if( isEnum )
127 {
128 pClass->SetClassType( CClass::Enum );
129 }
130 else if( isDelegate )
131 {
132 pClass->SetClassType( CClass::Delegate );
133 }
134 else{
135 pClass->SetClassType( CClass::Class );
136 }
137 }
138 else if( source[nowLine+1] == ESC_INTERFACE ){
139 pClass->SetClassType( CClass::Interface );
140 }
141 else{
142 pClass->SetClassType( CClass::Structure );
143 }
144 }
145
146 // Blittable型の場合
147 if( !blittableType.IsNull() ){
148 pClass->SetBlittableType( blittableType );
149
150 // Blittable型として登録
151 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
152 }
153 }
154 }
155}
156
157
158class CLoopRefCheck{
159 char **names;
160 int num;
161 void init(){
162 int i;
163 for(i=0;i<num;i++){
164 free(names[i]);
165 }
166 free(names);
167 }
168public:
169 CLoopRefCheck()
170 {
171 names=(char **)malloc(1);
172 num=0;
173 }
174 ~CLoopRefCheck()
175 {
176 init();
177 }
178 void add(const char *lpszInheritsClass)
179 {
180 names=(char **)realloc(names,(num+1)*sizeof(char *));
181 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
182 lstrcpy(names[num],lpszInheritsClass);
183 num++;
184 }
185 void del(const char *lpszInheritsClass)
186 {
187 int i;
188 for(i=0;i<num;i++){
189 if(lstrcmp(names[i],lpszInheritsClass)==0){
190 free(names[i]);
191 break;
192 }
193 }
194 if(i!=num){
195 num--;
196 for(;i<num;i++){
197 names[i]=names[i+1];
198 }
199 }
200 }
201 BOOL check(const CClass &inheritsClass) const
202 {
203 //ループ継承チェック
204 int i;
205 for(i=0;i<num;i++){
206 if( inheritsClass.GetName() == names[i] ){
207 return 1;
208 }
209 }
210 return 0;
211 }
212};
213CLoopRefCheck *pobj_LoopRefCheck;
214
215bool MemberVar_LoopRefCheck(const CClass &objClass){
216 if( objClass.HasSuperClass() )
217 {
218 // 基底クラスをチェック
219 if( MemberVar_LoopRefCheck( objClass.GetSuperClass() ) == false )
220 {
221 return false;
222 }
223 }
224
225 bool result = true;
226 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
227 if(pMember->GetType().IsStruct()){
228 //循環参照でないかをチェック
229 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
230 extern int cp;
231 compiler.errorMessenger.Output(124,pMember->GetType().GetClass().GetName(),cp);
232 return false;
233 }
234
235 pobj_LoopRefCheck->add(objClass.GetName().c_str());
236
237 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
238 if( result )
239 {
240 result = tempResult;
241 }
242
243 pobj_LoopRefCheck->del(objClass.GetName().c_str());
244 }
245 }
246
247 return result;
248}
249
250void OverrideErrorCheck( const DynamicMethod::OverrideResult &result )
251{
252 switch( result.enumType )
253 {
254 case DynamicMethod::OverrideResult::Successful:
255 break;
256 case DynamicMethod::OverrideResult::NotVirtual:
257 compiler.errorMessenger.Output(136, result.pMethod->GetUserProc().GetName(), cp);
258 break;
259 case DynamicMethod::OverrideResult::NotUseOverrideModifier:
260 compiler.errorMessenger.Output(127, result.pMethod->GetUserProc().GetName(), cp);
261 break;
262 case DynamicMethod::OverrideResult::DifferentAccesibility:
263 compiler.errorMessenger.Output(128, result.pMethod->GetUserProc().GetName(), cp);
264 break;
265 default:
266 throw;
267 }
268}
269
270void LexicalAnalyzer::AddMethod(CClass *pobj_c, UserProc *pUserProc, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
271 bool isVirtual, bool isOverride, const char *interfaceName, bool isAutoGeneration, int nowLine)
272{
273 if( isAutoGeneration )
274 {
275 // コード自動生成
276 pUserProc->ThisIsAutoGenerationProc();
277 }
278
279
280 ////////////////////////////////////////////////////////////
281 // コンストラクタ、デストラクタの場合の処理
282 ////////////////////////////////////////////////////////////
283 BOOL fConstructor=0,bDestructor=0;
284
285 if( pUserProc->GetName() == pobj_c->GetName() ){
286 //コンストラクタの場合
287
288 //標準コンストラクタ(引数なし)
289 if(pUserProc->Params().size()==0) fConstructor=1;
290
291 //強制的にConst修飾子をつける
292 isConst = true;
293 }
294 else if(pUserProc->GetName()[0]=='~'){
295 //デストラクタの場合はその名前が正しいかチェックを行う
296 if(lstrcmp(pUserProc->GetName().c_str()+1,pobj_c->GetName().c_str())!=0)
297 compiler.errorMessenger.Output(117,NULL,nowLine);
298 else
299 bDestructor=1;
300 }
301 if(fConstructor||bDestructor){
302 // コンストラクタ、デストラクタのアクセシビリティをチェック
303
304 //強制的にConst修飾子をつける
305 isConst = true;
306 }
307
308 if( fConstructor == 1 )
309 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
310 else if( bDestructor )
311 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
312
313
314
315 //////////////////
316 // 重複チェック
317 //////////////////
318
319 if(pobj_c->DupliCheckMember( pUserProc->GetName().c_str() )){
320 compiler.errorMessenger.Output(15,pUserProc->GetName(),nowLine);
321 return;
322 }
323
324 //メソッド
325 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
326 {
327 //基底クラスと重複する場合はオーバーライドを行う
328 if( pMethod->GetInheritsClassPtr() ) continue;
329
330 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
331 {
332 //関数名、パラメータ、戻り値が合致したとき
333 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
334 return;
335 }
336 }
337
338 //仮想関数の場合
339 if( isAbstract ) pUserProc->CompleteCompile();
340
341 // メソッドのオーバーライド
342 DynamicMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
343 if( pMethodForOverride )
344 {
345 DynamicMethod::OverrideResult result;
346 result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isOverride );
347 result.pMethod = pMethodForOverride;
348 OverrideErrorCheck( result );
349
350 pUserProc->SetMethod( pMethodForOverride );
351 return;
352 }
353 else
354 {
355 // インターフェイス メソッドのオーバーライド
356 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
357 {
358 if( interfaceName[0] )
359 {
360 if( pInterface->GetClass().GetName() != interfaceName )
361 {
362 // 指定されたインターフェイス名と整合しないとき
363 continue;
364 }
365 }
366
367 if( !pInterface->GetClass().IsReady() ){
368 // インターフェイスが未解析のとき
369 LexicalAnalyzer::LookaheadClass(
370 pInterface->GetClass().GetName().c_str(),
371 compiler.GetObjectModule().meta.GetClasses()
372 );
373 }
374
375 DynamicMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
376 if( pMethodForOverride )
377 {
378 DynamicMethod::OverrideResult result;
379 result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isOverride );
380 result.pMethod = pMethodForOverride;
381 OverrideErrorCheck( result );
382
383 pUserProc->SetMethod( pMethodForOverride );
384 return;
385 }
386 }
387 }
388
389 if( interfaceName[0] )
390 {
391 compiler.errorMessenger.Output(139,interfaceName,nowLine);
392 }
393
394 if( isVirtual ){
395 pobj_c->AddVtblNum( 1 );
396 }
397
398 if( isOverride ){
399 compiler.errorMessenger.Output(12,"Override",nowLine);
400 }
401
402 if(bStatic){
403 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
404 }
405 else{
406 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
407 }
408}
409
410bool LexicalAnalyzer::Inherits( CClass &currentClass, const char *inheritNames, int nowLine ){
411 int i = 0;
412 bool isInheritsClass = false;
413 while( true ){
414
415 char temporary[VN_SIZE];
416 for( int i2=0;; i++, i2++ ){
417 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
418 temporary[i2] = 0;
419 break;
420 }
421 temporary[i2] = inheritNames[i];
422 }
423
424 // ジェネリクス構文を分解
425 char className[VN_SIZE];
426 Jenga::Common::Strings typeParameterStrings;
427 SplitGenericClassInstance( temporary, className, typeParameterStrings );
428
429 // 型パラメータ文字列から型データを取得
430 Types actualTypeParameters;
431 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
432 {
433 Type type;
434 compiler.StringToType( typeParameterStr, type );
435 actualTypeParameters.push_back( type );
436 }
437
438 //継承元クラスを取得
439 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
440 if( !pInheritsClass ){
441 compiler.errorMessenger.Output(106,className,nowLine);
442 return false;
443 }
444
445 if( pInheritsClass->IsClass() ){
446 // クラスを継承する
447 isInheritsClass = true;
448
449 //ループ継承でないかをチェック
450 if( !LexicalAnalyzer::LoopRefCheck(*pInheritsClass) )
451 {
452 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),nowLine);
453 return false;
454 }
455
456 if( !pInheritsClass->IsReady() ){
457 //継承先が読み取られていないとき
458 LexicalAnalyzer::LookaheadClass(
459 pInheritsClass->GetName().c_str(),
460 compiler.GetObjectModule().meta.GetClasses()
461 );
462 }
463
464 if( !currentClass.InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
465 return false;
466 }
467 }
468 else{
469 compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine);
470 return false;
471 }
472
473 if( inheritNames[i] == '\0' ){
474 break;
475 }
476 i++;
477 }
478
479 if( !isInheritsClass ){
480 const CClass *pObjectClass = compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
481 //ループ継承でないかをチェック
482 if( !LexicalAnalyzer::LoopRefCheck( *pObjectClass ) )
483 {
484 compiler.errorMessenger.Output(123,pObjectClass->GetName(),nowLine);
485 return false;
486 }
487
488 if( !pObjectClass->IsReady() ){
489 //継承先が読み取られていないとき
490 LexicalAnalyzer::LookaheadClass(
491 pObjectClass->GetName().c_str(),
492 compiler.GetObjectModule().meta.GetClasses()
493 );
494 }
495
496 // クラスを一つも継承していないとき
497 if( !currentClass.InheritsClass( *pObjectClass, Types(), nowLine ) ){
498 return false;
499 }
500 }
501
502 return true;
503}
504
505bool LexicalAnalyzer::Implements( CClass &currentClass, const char *interfaceNames, int nowLine )
506{
507 Jenga::Common::Strings paramStrs;
508 SplitParameter( interfaceNames, paramStrs );
509
510 BOOST_FOREACH( const std::string &paramStr, paramStrs )
511 {
512 char className[VN_SIZE];
513 Jenga::Common::Strings typeParameterStrings;
514 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
515
516 Types actualTypeParameters;
517 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
518 {
519 Type type;
520 compiler.StringToType( typeParameterStr, type );
521 actualTypeParameters.push_back( type );
522 }
523
524 //継承元クラスを取得
525 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( className );
526 if( !pInterfaceClass ){
527 compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine);
528 continue;
529 }
530
531 if( !pInterfaceClass->IsReady() ){
532 // インターフェイスが未解析のとき
533 LexicalAnalyzer::LookaheadClass(
534 pInterfaceClass->GetName().c_str(),
535 compiler.GetObjectModule().meta.GetClasses()
536 );
537 }
538
539 if( pInterfaceClass->IsInterface() || pInterfaceClass->IsComInterface() )
540 {
541 // インターフェイスを継承する
542 std::vector<DynamicMethod::OverrideResult> overrideResults;
543 currentClass.Implements( *pInterfaceClass, actualTypeParameters, overrideResults );
544
545 // エラーチェック
546 BOOST_FOREACH( const DynamicMethod::OverrideResult result, overrideResults )
547 {
548 OverrideErrorCheck( result );
549 }
550 }
551 else
552 {
553 // インターフェイスではないとき
554 compiler.errorMessenger.Output(138,pInterfaceClass->GetName().c_str(),nowLine );
555 }
556 }
557
558 return true;
559}
560
561void GetClass_recur( const char *lpszInheritsClass, Classes &classes )
562{
563 extern char *basbuf;
564 int i,i2,i3,sub_address,top_pos;
565 char temporary[8192];
566
567 // 名前空間管理
568 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
569 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
570 namespaceScopes.clear();
571
572 // Importsされた名前空間の管理
573 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
574 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
575
576 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
577 const CClass *pBackCompilingClass = compiler.IsCompilingClass()
578 ? &compiler.GetCompilingClass()
579 : NULL;
580
581 for(i=0;;i++){
582 if(basbuf[i]=='\0') break;
583
584
585 // 名前空間
586 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
587 for(i+=2,i2=0;;i2++,i++){
588 if( IsCommandDelimitation( basbuf[i] ) ){
589 temporary[i2]=0;
590 break;
591 }
592 temporary[i2]=basbuf[i];
593 }
594 namespaceScopes.push_back( temporary );
595
596 continue;
597 }
598 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
599 if( namespaceScopes.size() <= 0 ){
600 compiler.errorMessenger.Output(12, "End Namespace", i );
601 }
602 else{
603 namespaceScopes.pop_back();
604 }
605
606 i += 2;
607 continue;
608 }
609
610 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
611 for(i+=2,i2=0;;i2++,i++){
612 if( IsCommandDelimitation( basbuf[i] ) ){
613 temporary[i2]=0;
614 break;
615 }
616 temporary[i2]=basbuf[i];
617 }
618 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
619 {
620 compiler.errorMessenger.Output(64,temporary,i );
621 }
622
623 continue;
624 }
625 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
626 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
627 continue;
628 }
629
630
631
632 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
633 //////////////////////////
634 // インターフェイス
635 //////////////////////////
636
637 top_pos=i;
638
639 i+=2;
640
641 //インターフェイス名を取得
642 GetCommandToken( temporary, basbuf, i );
643
644 char className[VN_SIZE];
645 Jenga::Common::Strings typeParameters;
646 Jenga::Common::Strings typeParameterBaseClassNames;
647 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
648
649 CClass *pobj_c = const_cast<CClass *>( classes.Find(namespaceScopes, className) );
650 if(!pobj_c) continue;
651
652 compiler.SetCompilingClass( pobj_c );
653
654 if(lpszInheritsClass){
655 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
656 //継承先先読み用
657 continue;
658 }
659 }
660
661 if(pobj_c->IsReady()){
662 //既に先読みされているとき
663 continue;
664 }
665
666 /////////////////////////////////////////////////////////
667 // ☆★☆ ジェネリクスサポート ☆★☆
668 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
669 {
670 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
671 if( typeParameterBaseClassNames[i2].size() )
672 {
673 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
674 {
675 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
676 }
677 else if( !baseType.IsObject() )
678 {
679 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
680 }
681 }
682
683 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
684 }
685 /////////////////////////////////////////////////////////
686
687 pobj_c->Readed();
688
689 pobj_c->SetConstructorMemberSubIndex( -1 );
690 pobj_c->SetDestructorMemberSubIndex( -1 );
691
692 if( memcmp( basbuf+i+1, "__COM", 5 ) == 0 && IsCommandDelimitation( basbuf[i+1+5] ) )
693 {
694 // COMインターフェイス
695 pobj_c->SetClassType( CClass::ComInterface );
696
697 i += 6;
698 }
699
700 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
701 //継承を行う場合
702 for(i+=3,i2=0;;i++,i2++){
703 if(IsCommandDelimitation(basbuf[i])){
704 temporary[i2]=0;
705 break;
706 }
707 temporary[i2]=basbuf[i];
708 }
709
710 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
711 compiler.errorMessenger.Output(105,temporary,i);
712 goto Interface_InheritsError;
713 }
714
715 //継承元クラスを取得
716 const CClass *pInheritsClass = classes.Find(temporary);
717 if( !pInheritsClass ){
718 compiler.errorMessenger.Output(106,temporary,i);
719 goto Interface_InheritsError;
720 }
721
722 //ループ継承でないかをチェック
723 if( !LexicalAnalyzer::LoopRefCheck( *pInheritsClass ) )
724 {
725 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),i);
726 goto Interface_InheritsError;
727 }
728
729 //継承させる
730 if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){
731 goto Interface_InheritsError;
732 }
733 }
734 else{
735 //継承無し
736 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
737 {
738 // TODO: ここに来ないことが実証できたらこの分岐は消す
739 Jenga::Throw( "GetClass_recur内の例外" );
740 }
741 }
742Interface_InheritsError:
743
744 //メンバ変数、関数を取得
745 while(1){
746 i++;
747
748 //エラー
749 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
750 compiler.errorMessenger.Output(22,"Interface",i);
751 i--;
752 break;
753 }
754
755 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
756 compiler.errorMessenger.Output(111,NULL,i);
757 break;
758 }
759 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
760 {
761 compiler.errorMessenger.Output(137, NULL, i );
762 break;
763 }
764
765 sub_address=i;
766
767 for(i2=0;;i++,i2++){
768 if(IsCommandDelimitation(basbuf[i])){
769 temporary[i2]=0;
770 break;
771 }
772 temporary[i2]=basbuf[i];
773 }
774 if(temporary[0]=='\0'){
775 if(basbuf[i]=='\0'){
776 i--;
777 compiler.errorMessenger.Output(22,"Interface",top_pos);
778 break;
779 }
780 continue;
781 }
782
783 //End Interface記述の場合
784 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
785
786 if(!(temporary[0]==1&&(
787 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
788 ))){
789 compiler.errorMessenger.Output(1,NULL,i);
790 break;
791 }
792
793 //関数ハッシュへ登録
794 char interfaceName[VN_SIZE] = "";
795 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,true,pobj_c, false, interfaceName );
796 if( pUserProc )
797 {
798 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, i );
799
800 //メンバ関数を追加
801 LexicalAnalyzer::AddMethod(pobj_c,
802 pUserProc,
803 Prototype::Public, //Publicアクセス権
804 0, // bStatic
805 false, // isConst
806 true, // isAbstract
807 true, // isVirtual
808 false, // isOverride
809 interfaceName,
810 false, // isAutoGeneration
811 sub_address
812 );
813 }
814 }
815 }
816
817 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
818 //////////////////////////
819 // クラス
820 //////////////////////////
821
822 top_pos=i;
823
824 const DWORD dwClassType=basbuf[i+1];
825
826 i+=2;
827
828 int iAlign=0;
829 if(memicmp(basbuf+i,"Align(",6)==0){
830 //アラインメント修飾子
831 i+=6;
832 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
833 iAlign=atoi(temporary);
834
835 if( dwClassType != ESC_TYPE )
836 {
837 compiler.errorMessenger.Output(140,NULL,i);
838 }
839
840 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
841 compiler.errorMessenger.Output(51,NULL,i);
842 }
843 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
844 // Blittable修飾子
845 i+=10;
846 i=JumpStringInPare(basbuf,i)+1;
847
848 if( dwClassType != ESC_CLASS )
849 {
850 compiler.errorMessenger.Output(141,NULL,i);
851 }
852 }
853
854 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
855 {
856 // 列挙型の場合
857 i += 2;
858 }
859 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
860 {
861 // デリゲートの場合
862 i += 2;
863 }
864
865 //クラス名を取得
866 GetCommandToken( temporary, basbuf, i );
867
868 char className[VN_SIZE];
869 Jenga::Common::Strings typeParameters;
870 Jenga::Common::Strings typeParameterBaseClassNames;
871 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
872
873 CClass *pobj_c = const_cast<CClass *>( classes.Find(namespaceScopes, className) );
874 if(!pobj_c) continue;
875
876 compiler.SetCompilingClass( pobj_c );
877
878 if(lpszInheritsClass){
879 if( pobj_c->GetName() != lpszInheritsClass ){
880 //継承先先読み用
881 continue;
882 }
883 }
884
885 if( lstrcmp(className,"Control")==0)
886 {
887 int test=0;
888 }
889
890 if(pobj_c->IsReady()){
891 //既に先読みされているとき
892 continue;
893 }
894
895
896 /////////////////////////////////////////////////////////
897 // ☆★☆ ジェネリクスサポート ☆★☆
898 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
899 {
900 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
901 if( typeParameterBaseClassNames[i2].size() )
902 {
903 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
904 {
905 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
906 }
907 else if( !baseType.IsObject() )
908 {
909 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
910 }
911 }
912
913 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
914 }
915 /////////////////////////////////////////////////////////
916
917
918 pobj_c->SetFixedAlignment( iAlign );
919
920 pobj_c->Readed();
921
922 pobj_c->SetConstructorMemberSubIndex( -1 );
923 pobj_c->SetDestructorMemberSubIndex( -1 );
924
925 //アクセス制限の初期値をセット
926 Prototype::Accessibility accessibility;
927 if(dwClassType==ESC_CLASS){
928 accessibility = Prototype::Private;
929 }
930 else{
931 accessibility = Prototype::Public;
932 }
933
934 if( pobj_c->GetName() == "Object"
935 || dwClassType == ESC_TYPE )
936 {
937 // 何も継承しない
938
939 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
940 {
941 // TODO: ここに来ないことが実証できたらこの分岐は消す
942 Jenga::Throw( "GetClass_recur内の例外" );
943 }
944 }
945 else{
946 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS)
947 {
948 // クラス継承先が指定されているとき
949 i += 3;
950 GetCommandToken( temporary, basbuf, i );
951
952 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
953 compiler.errorMessenger.Output(105,temporary,i);
954 goto InheritsError;
955 }
956 }
957 else
958 {
959 // 何の指定もないときはObjectクラスを継承する
960 lstrcpy( temporary, "Object" );
961 }
962 LexicalAnalyzer::Inherits( *pobj_c, temporary, i );
963
964 if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS )
965 {
966 // インターフェイス実装を行う場合
967 i += 3;
968 GetCommandToken( temporary, basbuf, i );
969
970 LexicalAnalyzer::Implements( *pobj_c, temporary, i );
971 }
972 }
973InheritsError:
974
975 //メンバとメソッドを取得
976 while(1){
977 i++;
978
979 //エラー
980 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
981 compiler.errorMessenger.Output(22,"Class",i);
982 i--;
983 break;
984 }
985
986 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
987 compiler.errorMessenger.Output(111,NULL,i);
988 break;
989 }
990 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
991 {
992 compiler.errorMessenger.Output(137, NULL, i );
993 break;
994 }
995
996 //Static修飾子
997 BOOL bStatic;
998 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
999 bStatic=1;
1000 i+=2;
1001 }
1002 else bStatic=0;
1003
1004 //Const修飾子
1005 bool isConst = false;
1006 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1007 isConst = true;
1008 i += 2;
1009 }
1010
1011 if(basbuf[i]==1&&(
1012 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1013 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1014 )){
1015 i3=basbuf[i+1];
1016 sub_address=i;
1017 }
1018 else i3=0;
1019
1020 bool isVirtual = false, isAbstract = false, isOverride = false;
1021 if(i3==ESC_ABSTRACT){
1022 isAbstract=1;
1023 isVirtual=1;
1024 i+=2;
1025
1026 i3=basbuf[i+1];
1027 }
1028 else if(i3==ESC_VIRTUAL){
1029 isAbstract=0;
1030 isVirtual=1;
1031 i+=2;
1032
1033 i3=basbuf[i+1];
1034 }
1035 else if(i3==ESC_OVERRIDE){
1036 isOverride=1;
1037 isVirtual=1;
1038
1039 i+=2;
1040
1041 i3=basbuf[i+1];
1042 }
1043
1044 for(i2=0;;i++,i2++){
1045 if(IsCommandDelimitation(basbuf[i])){
1046 temporary[i2]=0;
1047 break;
1048 }
1049 temporary[i2]=basbuf[i];
1050 }
1051 if(temporary[0]=='\0'){
1052 if(basbuf[i]=='\0'){
1053
1054 if(dwClassType==ESC_CLASS)
1055 compiler.errorMessenger.Output(22,"Class",top_pos);
1056 else
1057 compiler.errorMessenger.Output(22,"Type",top_pos);
1058
1059 i--;
1060 break;
1061 }
1062 continue;
1063 }
1064
1065 //End Class記述の場合
1066 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1067 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1068
1069 //アクセスを変更
1070 if(lstrcmpi(temporary,"Private")==0){
1071 accessibility = Prototype::Private;
1072 continue;
1073 }
1074 if(lstrcmpi(temporary,"Public")==0){
1075 accessibility = Prototype::Public;
1076 continue;
1077 }
1078 if(lstrcmpi(temporary,"Protected")==0){
1079 accessibility = Prototype::Protected;
1080 continue;
1081 }
1082
1083 extern int cp;
1084 if(i3==0){
1085 if(bStatic){
1086 //静的メンバを追加
1087 cp=i; //エラー用
1088 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
1089 }
1090 else{
1091 //メンバを追加
1092 cp=i; //エラー用
1093 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
1094
1095
1096 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
1097 if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
1098 //参照先が読み取られていないとき
1099 GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
1100 }
1101 }
1102
1103
1104 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
1105 //循環参照のチェック
1106 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1107 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
1108 //エラー回避
1109 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
1110 type.SetBasicType( DEF_PTR_VOID );
1111 }
1112 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1113 }
1114 }
1115 }
1116 else{
1117 //関数ハッシュへ登録
1118 char interfaceName[VN_SIZE] = "";
1119 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,isVirtual,pobj_c, (bStatic!=0), interfaceName );
1120 if( pUserProc )
1121 {
1122 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, i );
1123
1124 //メソッドを追加
1125 cp=i; //エラー用
1126 LexicalAnalyzer::AddMethod(pobj_c,
1127 pUserProc,
1128 accessibility,
1129 bStatic,
1130 isConst,
1131 isAbstract,
1132 isVirtual,
1133 isOverride,
1134 interfaceName,
1135 false,
1136 sub_address);
1137 }
1138
1139 if( isAbstract ) continue;
1140
1141 for(;;i++){
1142 if(basbuf[i]=='\0'){
1143 i--;
1144 break;
1145 }
1146 if(basbuf[i-1]!='*'&&
1147 basbuf[i]==1&&(
1148 basbuf[i+1]==ESC_SUB||
1149 basbuf[i+1]==ESC_FUNCTION||
1150 basbuf[i+1]==ESC_MACRO||
1151 basbuf[i+1]==ESC_TYPE||
1152 basbuf[i+1]==ESC_CLASS||
1153 basbuf[i+1]==ESC_INTERFACE||
1154 basbuf[i+1]==ESC_ENUM)){
1155 GetDefaultNameFromES(i3,temporary);
1156 compiler.errorMessenger.Output(22,temporary,i);
1157 }
1158 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1159 i+=2;
1160 break;
1161 }
1162 }
1163 }
1164 }
1165 }
1166 }
1167
1168 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
1169 compiler.SetCompilingClass( pBackCompilingClass );
1170
1171 // 名前空間を元に戻す
1172 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1173
1174 // インポートされた名前空間を元に戻す
1175 compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces;
1176}
1177
1178void LexicalAnalyzer::LookaheadClass( const char *className, Classes &classes )
1179{
1180 pobj_LoopRefCheck->add( className );
1181 GetClass_recur( className, classes );
1182 pobj_LoopRefCheck->del( className );
1183}
1184
1185bool LexicalAnalyzer::LoopRefCheck( const CClass &objClass )
1186{
1187 if( pobj_LoopRefCheck->check( objClass ) )
1188 {
1189 return false;
1190 }
1191
1192 return true;
1193}
1194
1195void LexicalAnalyzer::CollectClasses( const char *source, Classes &classes ){
1196 //ループ継承チェック用のクラス
1197 pobj_LoopRefCheck=new CLoopRefCheck();
1198
1199 //クラスを取得
1200 GetClass_recur( 0, classes );
1201
1202 delete pobj_LoopRefCheck;
1203 pobj_LoopRefCheck=0;
1204
1205 // イテレータの準備
1206 classes.Iterator_Init();
1207}
Note: See TracBrowser for help on using the repository browser.