00001 #include "stdafx.h"
00002
00003 #include "BON.h"
00004 #include "BONImpl.h"
00005
00006 #include "ReferenceRep.h"
00007 #include "ModelRep.h"
00008 #include "CodeGen.h"
00009
00010
00011 #include "algorithm"
00012
00013 #include "globals.h"
00014 extern Globals global_vars;
00015 extern int h_ind;
00016
00017 ReferenceRep::ReferenceRep( BON::FCO& ptr, BON::FCO& resp_ptr)
00018 : FCO( ptr, resp_ptr)
00019 , m_initialReferees()
00020 , m_finalReferees()
00021 , m_allReferees()
00022 {
00023 }
00024
00025
00026 ReferenceRep::~ReferenceRep()
00027 {
00028 m_initialReferees.clear();
00029 m_finalReferees.clear();
00030 m_allReferees.clear();
00031 }
00032
00033
00034 void ReferenceRep::addInitialReferee( FCO * refd )
00035 {
00036 if ( std::find( m_initialReferees.begin(), m_initialReferees.end(), refd)
00037 == m_initialReferees.end())
00038 m_initialReferees.push_back( refd );
00039 else
00040 global_vars.err << "Warning: Reference \"" << getName() << "\" referring twice to fco: \"" << refd->getName() << "\". Disregarded.\n";
00041 }
00042
00043
00044 FCO * ReferenceRep::getInitialReferee() const
00045 {
00046 if (checkNotEmpty()) return m_initialReferees[0];
00047 else return 0;
00048 }
00049
00050
00051 const ReferenceRep::RefereeList& ReferenceRep::getInitialReferees() const
00052 {
00053 return m_initialReferees;
00054 }
00055
00056
00057 const ReferenceRep::RefereeList& ReferenceRep::getFinalReferees() const
00058 {
00059 return m_finalReferees;
00060 }
00061
00062
00063
00064
00065
00066
00067
00068 bool ReferenceRep::pointsToModels() const
00069 {
00070 int how_many_models = 0;
00071 std::string which_models;
00072 bool value_set = false;
00073 bool to_models = true;
00074 KIND_TYPE kind;
00075
00076 for( unsigned int i = 0; i < m_allReferees.size(); ++i)
00077 {
00078 kind = m_allReferees[i]->getMyKind();
00079 if( kind != Any::FCO_REP && kind != Any::REF)
00080 {
00081
00082 if ( !m_allReferees[i]->isAbstract())
00083 {
00084 to_models = to_models && (kind == Any::MODEL);
00085
00086 value_set = true;
00087
00088 if (kind == Any::MODEL)
00089 {
00090 how_many_models += 1;
00091 which_models += m_allReferees[i]->getName() + " ";
00092 }
00093 }
00094 }
00095 }
00096
00097 if (value_set) return to_models;
00098 else return false;
00099 }
00100
00101
00102
00103
00104
00105
00106 std::vector<const ModelRep *> ReferenceRep::getModelRefVector() const
00107 {
00108 std::vector<const ModelRep *> models;
00109 unsigned int i = 0;
00110 while( i < m_allReferees.size())
00111 {
00112 if ( m_allReferees[i]->getMyKind() == Any::MODEL && !m_allReferees[i]->isAbstract())
00113 {
00114 const ModelRep * c_m = dynamic_cast<const ModelRep*>( m_allReferees[i]);
00115 if ( std::find( models.begin(), models.end(), c_m) == models.end())
00116 models.push_back( c_m);
00117 }
00118 ++i;
00119 }
00120
00121 return models;
00122 }
00123
00124
00125 void ReferenceRep::addFinalReferees( FCO * referee)
00126 {
00127
00128 RefereeList_Iterator l_it = std::find( m_finalReferees.begin(), m_finalReferees.end(), referee);
00129
00130 if ( l_it == m_finalReferees.end())
00131 m_finalReferees.push_back( referee);
00132 else { }
00133
00134 referee->addFinalRefersToMe( this);
00135 }
00136
00137
00138 void ReferenceRep::addFinalReferees( RefereeList & referees )
00139 {
00140 RefereeList_Iterator referee_it = referees.begin();
00141 for( ; referee_it != referees.end(); ++referee_it)
00142 {
00143 addFinalReferees( *referee_it);
00144 (*referee_it)->addFinalRefersToMe( this);
00145 }
00146 }
00147
00148
00149 void ReferenceRep::inherit()
00150 {
00151 std::vector<FCO*> refnce_descendants;
00152 this->getImpDescendants( refnce_descendants);
00153 refnce_descendants.push_back( this);
00154
00155 RefereeList_Iterator it = m_initialReferees.begin();
00156 for( ; it != m_initialReferees.end(); ++it)
00157 {
00158 FCO * target_ptr = *it;
00159
00160 std::vector<FCO*> refree_descendants;
00161
00162
00163 target_ptr->getIntDescendants( refree_descendants);
00164
00165 std::vector<FCO*>::reverse_iterator refnce_it = refnce_descendants.rbegin();
00166 for( ; refnce_it != refnce_descendants.rend(); ++refnce_it)
00167 {
00168 if ( (*refnce_it)->getMyKind() != Any::REF)
00169 global_vars.err << "Non-Reference descendant: " << (*refnce_it)->getName() <<" of reference: " << getName() <<"\n";
00170 else
00171 {
00172 ReferenceRep* one_refnce = dynamic_cast<ReferenceRep *>(*refnce_it);
00173 one_refnce->addFinalReferees( target_ptr);
00174 one_refnce->addFinalReferees( refree_descendants);
00175 }
00176 }
00177 }
00178 }
00179
00180
00181 bool ReferenceRep::finalize()
00182 {
00183 bool value_set = false;
00184 bool same_kind = true;
00185 const ModelRep * mod_ptr = 0;
00186 KIND_TYPE kind;
00187
00188 std::vector<FCO*> all_referees( m_finalReferees);
00189
00190 unsigned int current = 0;
00191 while( !all_referees.empty() && current < all_referees.size())
00192 {
00193 if ( all_referees[current]->getMyKind() != Any::FCO_REP &&
00194 all_referees[current]->getMyKind() != Any::REF)
00195 {
00196 if (!value_set)
00197 {
00198 kind = all_referees[current]->getMyKind();
00199 value_set = true;
00200 }
00201 else
00202 same_kind = same_kind && (all_referees[current]->getMyKind() == kind);
00203 }
00204 else if ( all_referees[current]->getMyKind() == Any::REF)
00205 {
00206 ReferenceRep * r = dynamic_cast<ReferenceRep *>( all_referees[current]);
00207
00208 const RefereeList &list = r->getFinalReferees();
00209
00210 RefereeList_ConstIterator list_iter = list.begin();
00211 for( ; list_iter != list.end(); ++list_iter)
00212 if (std::find( all_referees.begin(), all_referees.end(), *list_iter) == all_referees.end())
00213 all_referees.push_back( *list_iter);
00214 }
00215 ++current;
00216 }
00217
00218 m_allReferees = all_referees;
00219
00220 return same_kind;
00221 }
00222
00223
00224 void ReferenceRep::createMethods()
00225 {
00226 if ( m_initialReferees.empty()) return;
00227
00228 std::string getter_src, getter_hdr;
00229 std::vector<FCO*> common_anc = FCO::lcdIntersect( m_finalReferees);
00230 if ( !common_anc.empty())
00231 {
00232 std::vector<FCO*>::iterator c_it = common_anc.begin();
00233 for( ; c_it != common_anc.end(); ++c_it)
00234 m_refGetterMethods.push_back( CodeGen::dumpRefGetter( this, *c_it, ""));
00235 }
00236 else if ( common_anc.empty())
00237 {
00238 std::string common_kind = FCO::lcdKindIntersect( m_finalReferees);
00239 m_refGetterMethods.push_back( CodeGen::dumpRefGetter( this, 0, common_kind));
00240 }
00241 else
00242 {
00243
00244
00245
00246 }
00247
00248
00249
00250
00251
00252
00253 }
00254
00255
00256 std::string ReferenceRep::doDump()
00257 {
00258 std::string h_file, c_file;
00259
00260 dumpPre( h_file, c_file);
00261 dumpFCO( h_file, c_file);
00262
00263 if ( !m_refGetterMethods.empty())
00264 h_file += CodeGen::indent(1) + "//\n" + CodeGen::indent(1) + "// ref getters\n";
00265
00266 MethodLexicographicSort lex;
00267 std::sort( m_refGetterMethods.begin(), m_refGetterMethods.end(), lex);
00268
00269 std::vector<Method>::iterator i = m_refGetterMethods.begin();
00270 for( ; i != m_refGetterMethods.end(); ++i)
00271 {
00272 h_file += i->getHeader() + "\n";
00273 c_file += i->getSource() + "";
00274 }
00275
00276 h_file += hideAndExpose();
00277
00278 dumpPost( h_file, c_file);
00279
00280 sendOutH( h_file);
00281 sendOutS( c_file);
00282
00283 return "";
00284 }
00285
00286
00287
00288
00289
00290
00291 bool ReferenceRep::checkNotEmpty() const
00292 {
00293 return !m_initialReferees.empty();
00294 }
00295
00296 bool ReferenceRep::checkAllTheSameKind() const
00297 {
00298 if ( !checkNotEmpty()) return false;
00299 if ( m_finalReferees.empty()) return false;
00300 if ( m_allReferees.empty()) return false;
00301
00302 bool all_the_same_kind = true;
00303
00304 bool value_set = false;
00305 bool same_kind = true;
00306 KIND_TYPE kind;
00307 for( unsigned int i = 0; i < m_allReferees.size(); ++i)
00308 {
00309 KIND_TYPE kind_of_i = m_allReferees[i]->getMyKind();
00310 if( kind_of_i != Any::FCO_REP && kind_of_i != Any::REF)
00311 {
00312 if (!value_set)
00313 {
00314 kind = kind_of_i;
00315 value_set = true;
00316 }
00317 else
00318 {
00319 same_kind = same_kind && ( kind_of_i == kind);
00320 if (kind_of_i != kind)
00321 {
00322
00323
00324
00325 }
00326 }
00327 }
00328 }
00329 if (value_set) return same_kind;
00330 else return false;
00331 }
00332
00333
00334 std::string ReferenceRep::refGetterTemplate( FCO * fco)
00335 {
00336 #if(LONG_NAMES)
00337 if (fco)
00338 return "get" + fco->getValidName() + "Referred";
00339 else
00340 return "getReferred";
00341 #else
00342 if (fco)
00343 {
00344 bool same_nmsp = fco->getValidNmspc() == getValidNmspc();
00345 return "get" + ( same_nmsp ? fco->getValidName() : ( fco->getValidNmspc() + fco->getValidName()));
00346 }
00347 else
00348 return "getReferred";
00349 #endif
00350 }
00351
00352
00353 std::string ReferenceRep::expose( const std::string& repl_container)
00354 {
00355 std::string h_file;
00356 h_file += FCO::expose( repl_container);
00357
00358 if (!m_refGetterMethods.empty())
00359 h_file += CodeGen::indent(h_ind) + "//\n" + CodeGen::indent(h_ind) + "// exposed ref getters\n";
00360 std::vector<Method>::iterator i = m_refGetterMethods.begin();
00361 for( ; i != m_refGetterMethods.end(); ++i)
00362 {
00363 h_file += i->getExposed( repl_container) + "\n";
00364 }
00365
00366 return h_file;
00367 }
00368
00369
00370 std::string ReferenceRep::hide()
00371 {
00372 std::string h_file;
00373 h_file += FCO::hide();
00374
00375 if (!m_refGetterMethods.empty())
00376 h_file += CodeGen::indent(h_ind) + "//\n" + CodeGen::indent(h_ind) + "// hidden ref getters\n";
00377 std::vector<Method>::iterator i = m_refGetterMethods.begin();
00378 for( ; i != m_refGetterMethods.end(); ++i)
00379 {
00380 h_file += i->getHidden() + "\n";
00381 }
00382
00383 return h_file;
00384 }
00385
00386