File indexing completed on 2023-06-12 23:39:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #include "FWCore/Reflection/interface/DictionaryTools.h"
0051
0052 #include "FWCore/Utilities/interface/Algorithms.h"
0053 #include "FWCore/Reflection/interface/BaseWithDict.h"
0054 #include "FWCore/Utilities/interface/EDMException.h"
0055 #include "FWCore/Utilities/interface/TypeID.h"
0056 #include "FWCore/Reflection/interface/TypeWithDict.h"
0057 #include "FWCore/Utilities/interface/WrappedClassName.h"
0058
0059 #include "TClass.h"
0060 #include "TClassEdit.h"
0061 #include "THashTable.h"
0062
0063 #include <algorithm>
0064 #include <sstream>
0065
0066 namespace edm {
0067
0068 bool checkDictionary(std::vector<std::string>& missingDictionaries, TypeID const& typeID) {
0069 TClass::GetClass(typeID.typeInfo());
0070 if (!hasDictionary(typeID.typeInfo())) {
0071
0072 TypeWithDict::byName(typeID.className());
0073 }
0074 if (!hasDictionary(typeID.typeInfo())) {
0075 missingDictionaries.emplace_back(typeID.className());
0076 return false;
0077 }
0078 return true;
0079 }
0080
0081 bool checkDictionaryOfWrappedType(std::vector<std::string>& missingDictionaries, TypeID const& unwrappedTypeID) {
0082 std::string wrappedName = wrappedClassName(unwrappedTypeID.className());
0083 TypeWithDict wrappedTypeWithDict = TypeWithDict::byName(wrappedName);
0084 return checkDictionary(missingDictionaries, wrappedName, wrappedTypeWithDict);
0085 }
0086
0087 bool checkDictionaryOfWrappedType(std::vector<std::string>& missingDictionaries, std::string const& unwrappedName) {
0088 std::string wrappedName = wrappedClassName(unwrappedName);
0089 TypeWithDict wrappedTypeWithDict = TypeWithDict::byName(wrappedName);
0090 return checkDictionary(missingDictionaries, wrappedName, wrappedTypeWithDict);
0091 }
0092
0093 bool checkDictionary(std::vector<std::string>& missingDictionaries,
0094 std::string const& name,
0095 TypeWithDict const& typeWithDict) {
0096 if (!bool(typeWithDict) || typeWithDict.invalidTypeInfo()) {
0097 missingDictionaries.emplace_back(name);
0098 return false;
0099 }
0100 return true;
0101 }
0102
0103 bool checkClassDictionaries(std::vector<std::string>& missingDictionaries, TypeID const& typeID) {
0104
0105
0106
0107
0108
0109
0110
0111 TClass* tClass = TClass::GetClass(typeID.typeInfo());
0112 if (!hasDictionary(typeID.typeInfo())) {
0113
0114 TypeWithDict::byName(typeID.className());
0115 tClass = TClass::GetClass(typeID.typeInfo());
0116 }
0117 if (!hasDictionary(typeID.typeInfo())) {
0118 missingDictionaries.emplace_back(typeID.className());
0119 return false;
0120 }
0121
0122 if (tClass == nullptr) {
0123 return true;
0124 }
0125
0126 bool result = true;
0127
0128 THashTable hashTable;
0129 bool recursive = true;
0130 tClass->GetMissingDictionaries(hashTable, recursive);
0131
0132 for (auto const& item : hashTable) {
0133 TClass const* cl = static_cast<TClass const*>(item);
0134 missingDictionaries.emplace_back(cl->GetName());
0135 result = false;
0136 }
0137 return result;
0138 }
0139
0140 bool checkClassDictionaries(std::vector<std::string>& missingDictionaries,
0141 std::string const& name,
0142 TypeWithDict const& typeWithDict) {
0143 if (!bool(typeWithDict) || typeWithDict.invalidTypeInfo()) {
0144 missingDictionaries.emplace_back(name);
0145 return false;
0146 }
0147
0148 TClass* tClass = typeWithDict.getClass();
0149 if (tClass == nullptr) {
0150 missingDictionaries.emplace_back(name);
0151 return false;
0152 }
0153
0154 THashTable hashTable;
0155 bool recursive = true;
0156 tClass->GetMissingDictionaries(hashTable, recursive);
0157
0158 bool result = true;
0159
0160 for (auto const& item : hashTable) {
0161 TClass const* cl = static_cast<TClass const*>(item);
0162 missingDictionaries.emplace_back(cl->GetName());
0163 result = false;
0164 }
0165 return result;
0166 }
0167
0168 void addToMissingDictionariesException(edm::Exception& exception,
0169 std::vector<std::string>& missingDictionaries,
0170 std::string const& context) {
0171 std::sort(missingDictionaries.begin(), missingDictionaries.end());
0172 missingDictionaries.erase(std::unique(missingDictionaries.begin(), missingDictionaries.end()),
0173 missingDictionaries.end());
0174
0175 std::ostringstream ostr;
0176 for (auto const& item : missingDictionaries) {
0177 ostr << " " << item << "\n";
0178 }
0179 exception << "No data dictionary found for the following classes:\n\n"
0180 << ostr.str() << "\n"
0181 << "Most likely each dictionary was never generated, but it may\n"
0182 << "be that it was generated in the wrong package. Please add\n"
0183 << "(or move) the specification \'<class name=\"whatever\"/>\' to\n"
0184 << "the appropriate classes_def.xml file along with any other\n"
0185 << "information needed there. For example, if this class has any\n"
0186 << "transient members, you need to specify them in classes_def.xml.\n"
0187 << "Also include the class header in classes.h\n";
0188
0189 if (!context.empty()) {
0190 exception.addContext(context);
0191 }
0192 }
0193
0194 void throwMissingDictionariesException(std::vector<std::string>& missingDictionaries, std::string const& context) {
0195 std::vector<std::string> empty;
0196 throwMissingDictionariesException(missingDictionaries, context, empty);
0197 }
0198
0199 void throwMissingDictionariesException(std::vector<std::string>& missingDictionaries,
0200 std::string const& context,
0201 std::vector<std::string>& producedTypes) {
0202 edm::Exception exception(errors::DictionaryNotFound);
0203 addToMissingDictionariesException(exception, missingDictionaries, context);
0204
0205 if (!producedTypes.empty()) {
0206 std::sort(producedTypes.begin(), producedTypes.end());
0207 producedTypes.erase(std::unique(producedTypes.begin(), producedTypes.end()), producedTypes.end());
0208
0209 std::ostringstream ostr;
0210 for (auto const& item : producedTypes) {
0211 ostr << " " << item << "\n";
0212 }
0213 exception << "\nA type listed above might or might not be the same as a\n"
0214 << "type declared by a producer module with the function \'produces\'.\n"
0215 << "Instead it might be the type of a data member, base class,\n"
0216 << "wrapped type, or other object needed by a produced type. Below\n"
0217 << "is some additional information which lists the types declared\n"
0218 << "to be produced by a producer module that are associated with\n"
0219 << "the types whose dictionaries were not found:\n\n"
0220 << ostr.str() << "\n";
0221 }
0222 throw exception;
0223 }
0224
0225 void throwMissingDictionariesException(std::vector<std::string>& missingDictionaries,
0226 std::string const& context,
0227 std::vector<std::string>& producedTypes,
0228 std::vector<std::string>& branchNames,
0229 bool fromStreamerSource) {
0230 edm::Exception exception(errors::DictionaryNotFound);
0231 addToMissingDictionariesException(exception, missingDictionaries, context);
0232
0233 if (!producedTypes.empty()) {
0234 std::sort(producedTypes.begin(), producedTypes.end());
0235 producedTypes.erase(std::unique(producedTypes.begin(), producedTypes.end()), producedTypes.end());
0236
0237 std::ostringstream ostr;
0238 for (auto const& item : producedTypes) {
0239 ostr << " " << item << "\n";
0240 }
0241 if (fromStreamerSource) {
0242 exception << "\nA type listed above might or might not be the same as a\n"
0243 << "type stored in the Event. Instead it might be the type of\n"
0244 << "a data member, base class, wrapped type, or other object\n"
0245 << "needed by a stored type. Below is some additional information\n"
0246 << "which lists the stored types associated with the types whose\n"
0247 << "dictionaries were not found:\n\n"
0248 << ostr.str() << "\n";
0249 } else {
0250 exception << "\nA type listed above might or might not be the same as a\n"
0251 << "type stored in the Event (or Lumi or Run). Instead it might\n"
0252 << "be the type of a data member, base class, wrapped type, or\n"
0253 << "other object needed by a stored type. Below is some additional\n"
0254 << "information which lists the stored types associated with the\n"
0255 << "types whose dictionaries were not found:\n\n"
0256 << ostr.str() << "\n";
0257 }
0258 }
0259
0260 if (!branchNames.empty()) {
0261 std::sort(branchNames.begin(), branchNames.end());
0262 branchNames.erase(std::unique(branchNames.begin(), branchNames.end()), branchNames.end());
0263
0264 std::ostringstream ostr;
0265 for (auto const& item : branchNames) {
0266 ostr << " " << item << "\n";
0267 }
0268 if (fromStreamerSource) {
0269 exception << "Missing dictionaries are associated with these branch names:\n\n" << ostr.str() << "\n";
0270 } else {
0271 exception << "Missing dictionaries are associated with these branch names:\n\n"
0272 << ostr.str() << "\n"
0273 << "If you do not need these branches and they are not produced\n"
0274 << "in the current process, an alternate solution to adding\n"
0275 << "dictionaries is to drop these branches on input using the\n"
0276 << "inputCommands parameter of the PoolSource.";
0277 }
0278 }
0279 throw exception;
0280 }
0281
0282 void throwMissingDictionariesException(std::vector<std::string>& missingDictionaries,
0283 std::string const& context,
0284 std::set<std::string>& producedTypes,
0285 bool consumedWithView) {
0286 edm::Exception exception(errors::DictionaryNotFound);
0287 addToMissingDictionariesException(exception, missingDictionaries, context);
0288
0289 if (!producedTypes.empty()) {
0290 std::ostringstream ostr;
0291 for (auto const& item : producedTypes) {
0292 ostr << " " << item << "\n";
0293 }
0294 if (consumedWithView) {
0295 exception << "\nThe list of types above was generated while checking for\n"
0296 << "dictionaries related to products declared to be consumed\n"
0297 << "using a View. They will be either the type or a base class\n"
0298 << "of the type declared in a consumes declaration as the template\n"
0299 << "parameter of a View. Below is some additional information\n"
0300 << "which lists the type of the template parameter of the View.\n"
0301 << "(It will be the same type unless the missing dictionary is\n"
0302 << "for a base type):\n\n"
0303 << ostr.str() << "\n";
0304 } else {
0305 exception << "\nThe list of types above was generated while checking for\n"
0306 << "dictionaries related to products declared to be consumed.\n"
0307 << "A type listed above might or might not be a type declared\n"
0308 << "to be consumed. Instead it might be the type of a data member,\n"
0309 << "base class, wrapped type or other object needed by a consumed\n"
0310 << "type. Below is some additional information which lists\n"
0311 << "the types declared to be consumed by a module and which\n"
0312 << "are associated with the types whose dictionaries were not\n"
0313 << "found:\n\n"
0314 << ostr.str() << "\n";
0315 }
0316 }
0317 throw exception;
0318 }
0319
0320 bool public_base_classes(std::vector<std::string>& missingDictionaries,
0321 TypeID const& typeID,
0322 std::vector<TypeID>& baseTypes) {
0323 if (!checkDictionary(missingDictionaries, typeID)) {
0324 return false;
0325 }
0326 TypeWithDict typeWithDict(typeID.typeInfo());
0327
0328 if (!typeWithDict.isClass()) {
0329 return true;
0330 }
0331
0332
0333
0334 if (TClassEdit::IsStdClass(typeWithDict.name().c_str())) {
0335 return true;
0336 }
0337
0338 TypeBases bases(typeWithDict);
0339 bool returnValue = true;
0340 for (auto const& basex : bases) {
0341 BaseWithDict base(basex);
0342 if (!base.isPublic()) {
0343 continue;
0344 }
0345 TypeWithDict baseRflxType = base.typeOf();
0346 if (!checkDictionary(missingDictionaries, baseRflxType.name(), baseRflxType)) {
0347 returnValue = false;
0348 continue;
0349 }
0350 TypeID baseType{baseRflxType.typeInfo()};
0351
0352
0353 if (!search_all(baseTypes, baseType)) {
0354
0355 baseTypes.push_back(baseType);
0356 if (!public_base_classes(missingDictionaries, baseType, baseTypes)) {
0357 returnValue = false;
0358 continue;
0359 }
0360 }
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 }
0381 return returnValue;
0382 }
0383
0384 }