4 #include "core/idlast/namespace.h"
5 #include "classtraits.h"
14 #include "subclasswrapper.h"
16 using namespace awful::awic
;
19 void awful::awic::GenerateClassTraitsFile( const idlast::Class
* pClass_
, bool bStruct_
)
21 string FullNamespaceName
;
23 const idlast::Namespace
* pCurrentNS
= pClass_
->getNamespace();
24 while( pCurrentNS
->getParent() )
26 FullNamespaceName
= pCurrentNS
->getName() + "::" + FullNamespaceName
;
27 pCurrentNS
= pCurrentNS
->getParent();
30 string FullClassName
= FullNamespaceName
+ pClass_
->getName();
32 string
name( pClass_
->getName() );
34 stringstream filename
;
35 filename
<< "traits_" << name
<< ".h";
37 ofstream
file( filename
.str().c_str() );
40 digest
.write( FullClassName
.c_str(), FullClassName
.size() );
43 "// Automatically generated by AWIC (AWful IDL Compiler).\n"
45 "#ifndef TRAITS_" << name
<< "_H_\n"
46 "#define TRAITS_" << name
<< "_H_\n\n"
47 "#include \"core/core.h\"\n"
48 "#include \"" << name
<< ".h\"\n\n"
52 OutputFlags( file
, pClass_
->getFlags(), FullClassName
);
54 file
<< "\ttemplate<> struct class_traits< " << FullClassName
<< " >\n"
56 "\t\tstatic uint32_t Digest() { return 0x" << std::hex
<< digest
.result() << "; }\n"
57 "\t\tstatic const char* Name() { return \"" << name
<< "\"; }\n"
58 "\t\tstatic const char* FullName() { return \"" << FullClassName
<< "\"; }\n"
59 "\t\ttypedef " << FullNamespaceName
<< "awful_tag module_tag;\n\n"
61 // Generate VisitSuperClasses
62 "\t\ttemplate< class V > static void VisitSuperClasses( V& Visitor_ )\n"
65 const std::list
< Pointer
< idlast::ClassRef
> >& SuperClasses( pClass_
->getSuperClasses() );
66 std::list
< Pointer
< idlast::ClassRef
> >::const_iterator scit
;
67 for( scit
= SuperClasses
.begin(); scit
!= SuperClasses
.end(); ++scit
)
69 file
<< "\t\t\tVisitor_.template declSuperClass< ";
70 PrintClassRef( file
, **scit
);
76 // Generate attribute tags
77 const idlast::Dictionary
< idlast::Attribute
>& Attributes( pClass_
->getAttributes() );
78 idlast::Dictionary
< idlast::Attribute
>::const_iterator atit
;
80 if( !Attributes
.empty() )
82 file
<< "\n\t\tstruct attribute_tags\n"
85 for( atit
= Attributes
.begin(); atit
!= Attributes
.end(); ++atit
)
87 idlast::Attribute
* pAttr
= atit
->second
;
88 file
<< "\t\t\tstruct " << pAttr
->getName() << " {};\n";
94 // Generate VisitAttributes
95 file
<< "\n\t\ttemplate< class V > static void VisitAttributes( V& Visitor_ )\n"
98 for( atit
= Attributes
.begin(); atit
!= Attributes
.end(); ++atit
)
100 idlast::Attribute
* pAttr
= atit
->second
;
101 file
<< "\t\t\tVisitor_.template declAttribute< attribute_tags::"
102 << pAttr
->getName() << " >();\n";
107 // Generate method tags
108 const idlast::Dictionary
< idlast::Method
>& Methods( pClass_
->getMethods() );
109 idlast::Dictionary
< idlast::Method
>::const_iterator mtdit
;
111 if( !Methods
.empty() )
113 file
<< "\n\t\tstruct method_tags\n"
116 for( mtdit
= Methods
.begin(); mtdit
!= Methods
.end(); ++mtdit
)
118 idlast::Method
* pMtd
= mtdit
->second
;
119 file
<< "\t\t\tstruct " << pMtd
->getName() << " {};\n";
125 // Generate VisitMethods
126 file
<< "\n\t\ttemplate< class V > static void VisitMethods( V& Visitor_ )\n"
129 for( mtdit
= Methods
.begin(); mtdit
!= Methods
.end(); ++mtdit
)
131 idlast::Method
* pMtd
= mtdit
->second
;
132 file
<< "\t\t\tVisitor_.template declMethod< method_tags::"
133 << pMtd
->getName() << " >();\n";
139 bool bAbstract
= pClass_
->testFlag( "Abstract", false );
141 const idlast::Overloads
& Constructors
= pClass_
->getConstructors();
142 if( !bAbstract
&& !Constructors
.empty() )
143 file
<< "\n\t\tstruct ctor_tag {};\n";
145 // Generate static method tags
146 const idlast::Dictionary
< idlast::Method
>& StaticMethods( pClass_
->getStaticMethods() );
148 if( !StaticMethods
.empty() )
150 file
<< "\n\t\tstruct static_method_tags\n"
153 for( mtdit
= StaticMethods
.begin(); mtdit
!= StaticMethods
.end(); ++mtdit
)
155 idlast::Method
* pMtd
= mtdit
->second
;
156 file
<< "\t\t\tstruct " << pMtd
->getName() << " {};\n";
162 // Generate VisitStaticMethods
163 file
<< "\n\t\ttemplate< class V > static void VisitStaticMethods( V& Visitor_ )\n"
166 // The constructors is considered to be a static method with overloads.
167 // Calling declConstructor() on the visitor serves to indicate that
168 // we have at least one constructor and that method_traits for it is available.
169 if( !bAbstract
&& !Constructors
.empty() )
170 file
<< "\t\t\tVisitor_.declConstructor();\n";
172 for( mtdit
= StaticMethods
.begin(); mtdit
!= StaticMethods
.end(); ++mtdit
)
174 idlast::Method
* pMtd
= mtdit
->second
;
175 file
<< "\t\t\tVisitor_.template declStaticMethod< static_method_tags::"
176 << pMtd
->getName() << " >();\n";
181 // Generate signal tags
182 const idlast::Dictionary
< idlast::Signal
>& Signals( pClass_
->getSignals() );
183 idlast::Dictionary
< idlast::Signal
>::const_iterator sigit
;
185 if( !Signals
.empty() )
187 file
<< "\n\t\tstruct signal_tags\n"
190 for( sigit
= Signals
.begin(); sigit
!= Signals
.end(); ++sigit
)
192 idlast::Signal
* pSig
= sigit
->second
;
193 file
<< "\t\t\tstruct " << pSig
->getName() << " {};\n";
199 // Generate VisitSignals
200 file
<< "\n\t\ttemplate< class V > static void VisitSignals( V& Visitor_ )\n"
203 for( sigit
= Signals
.begin(); sigit
!= Signals
.end(); ++sigit
)
205 idlast::Signal
* pSig
= sigit
->second
;
206 file
<< "\t\t\tVisitor_.template declSignal< signal_tags::"
207 << pSig
->getName() << " >();\n";
212 // Generate enum tags
213 const idlast::Dictionary
< idlast::Enum
>& Enums( pClass_
->getEnums() );
214 idlast::Dictionary
< idlast::Enum
>::const_iterator enit
;
218 file
<< "\n\t\tstruct enum_tags\n"
221 for( enit
= Enums
.begin(); enit
!= Enums
.end(); ++enit
)
223 idlast::Enum
* pEnum
= enit
->second
;
224 file
<< "\t\t\tstruct " << pEnum
->getName() << " {};\n";
230 // Generate VisitEnums
231 file
<< "\n\t\ttemplate< class V > static void VisitEnums( V& Visitor_ )\n"
234 for( enit
= Enums
.begin(); enit
!= Enums
.end(); ++enit
)
236 idlast::Enum
* pEnum
= enit
->second
;
237 file
<< "\t\t\tVisitor_.template declEnum< enum_tags::"
238 << pEnum
->getName() << " >();\n";
244 // Generate sub-classing wrapper, if the class is extensible by scripts
245 if( pClass_
->testFlag( "ExtensibleByScript", false ) )
248 GenerateSubClassWrapper( file
, pClass_
, FullClassName
);
251 // Generate attributes traits
252 for( atit
= Attributes
.begin(); atit
!= Attributes
.end(); ++atit
)
254 idlast::Attribute
* pAttr
= atit
->second
;
255 GenerateAttrTraits( file
, pClass_
, pAttr
, bStruct_
);
258 // Generate constructor traits
259 if( !bAbstract
&& !Constructors
.empty() )
260 GenerateCtorTraits( file
, pClass_
, bStruct_
);
262 // Generate methods traits
263 for( mtdit
= Methods
.begin(); mtdit
!= Methods
.end(); ++mtdit
)
265 idlast::Method
* pMtd
= mtdit
->second
;
266 GenerateMethodTraits( file
, pClass_
, pMtd
, false );
269 // Generate static methods traits
270 for( mtdit
= StaticMethods
.begin(); mtdit
!= StaticMethods
.end(); ++mtdit
)
272 idlast::Method
* pMtd
= mtdit
->second
;
273 GenerateMethodTraits( file
, pClass_
, pMtd
, true );
276 // Generate signal traits
277 for( sigit
= Signals
.begin(); sigit
!= Signals
.end(); ++sigit
)
279 idlast::Signal
* pSig
= sigit
->second
;
280 GenerateSignalTraits( file
, pClass_
, pSig
);
283 // Generate enum traits
284 for( enit
= Enums
.begin(); enit
!= Enums
.end(); ++enit
)
286 idlast::Enum
* pEnum
= enit
->second
;
287 GenerateEnumTraits( file
, pEnum
);