awic compiles again.
[fail.git] / src / core / awic / classtraits.cpp
blob66df9756d35bd610c3c897c738ee05faacb64b38
1 #include <sstream>
2 #include <fstream>
3 #include <vector>
4 #include "core/idlast/namespace.h"
5 #include "classtraits.h"
6 #include "classref.h"
7 #include "type.h"
8 #include "attribute.h"
9 #include "method.h"
10 #include "signal.h"
11 #include "enum.h"
12 #include "flags.h"
13 #include "crc32.h"
14 #include "subclasswrapper.h"
16 using namespace awful::awic;
17 using namespace std;
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() );
39 crc32 digest;
40 digest.write( FullClassName.c_str(), FullClassName.size() );
42 file << "//\n"
43 "// Automatically generated by AWIC (AWful IDL Compiler).\n"
44 "//\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"
49 "namespace awful\n"
50 "{\n";
52 OutputFlags( file, pClass_->getFlags(), FullClassName );
54 file << "\ttemplate<> struct class_traits< " << FullClassName << " >\n"
55 "\t{\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"
63 "\t\t{\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 );
71 file << " >();\n";
74 file << "\t\t}\n";
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"
83 "\t\t{\n";
85 for( atit = Attributes.begin(); atit != Attributes.end(); ++atit )
87 idlast::Attribute* pAttr = atit->second;
88 file << "\t\t\tstruct " << pAttr->getName() << " {};\n";
91 file << "\t\t};\n";
94 // Generate VisitAttributes
95 file << "\n\t\ttemplate< class V > static void VisitAttributes( V& Visitor_ )\n"
96 "\t\t{\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";
105 file << "\t\t}\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"
114 "\t\t{\n";
116 for( mtdit = Methods.begin(); mtdit != Methods.end(); ++mtdit )
118 idlast::Method* pMtd = mtdit->second;
119 file << "\t\t\tstruct " << pMtd->getName() << " {};\n";
122 file << "\t\t};\n";
125 // Generate VisitMethods
126 file << "\n\t\ttemplate< class V > static void VisitMethods( V& Visitor_ )\n"
127 "\t\t{\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";
136 file << "\t\t}\n";
138 // Generate ctor tag
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"
151 "\t\t{\n";
153 for( mtdit = StaticMethods.begin(); mtdit != StaticMethods.end(); ++mtdit )
155 idlast::Method* pMtd = mtdit->second;
156 file << "\t\t\tstruct " << pMtd->getName() << " {};\n";
159 file << "\t\t};\n";
162 // Generate VisitStaticMethods
163 file << "\n\t\ttemplate< class V > static void VisitStaticMethods( V& Visitor_ )\n"
164 "\t\t{\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";
179 file << "\t\t}\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"
188 "\t\t{\n";
190 for( sigit = Signals.begin(); sigit != Signals.end(); ++sigit )
192 idlast::Signal* pSig = sigit->second;
193 file << "\t\t\tstruct " << pSig->getName() << " {};\n";
196 file << "\t\t};\n";
199 // Generate VisitSignals
200 file << "\n\t\ttemplate< class V > static void VisitSignals( V& Visitor_ )\n"
201 "\t\t{\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";
210 file << "\t\t}\n";
212 // Generate enum tags
213 const idlast::Dictionary< idlast::Enum >& Enums( pClass_->getEnums() );
214 idlast::Dictionary< idlast::Enum >::const_iterator enit;
216 if( !Enums.empty() )
218 file << "\n\t\tstruct enum_tags\n"
219 "\t\t{\n";
221 for( enit = Enums.begin(); enit != Enums.end(); ++enit )
223 idlast::Enum* pEnum = enit->second;
224 file << "\t\t\tstruct " << pEnum->getName() << " {};\n";
227 file << "\t\t};\n";
230 // Generate VisitEnums
231 file << "\n\t\ttemplate< class V > static void VisitEnums( V& Visitor_ )\n"
232 "\t\t{\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";
241 file << "\t\t}\n"
242 "\t};\n";
244 // Generate sub-classing wrapper, if the class is extensible by scripts
245 if( pClass_->testFlag( "ExtensibleByScript", false ) )
247 file << '\n';
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 );
290 file << "}"
291 "\n\n"
292 "#endif\n";