CMS 3D CMS Logo

findMethod.cc
Go to the documentation of this file.
2 
8 
9 #include <typeindex>
10 #include <cassert>
11 
13 
16 static bool fatalErrorCondition(const int err) {
20 }
21 
22 namespace reco {
23 
25  const edm::TypeWithDict& type,
26  const std::vector<AnyMethodArgument>& args,
27  std::vector<AnyMethodArgument>& fixuppedArgs) {
28  int casts = 0;
29  if (mem.isConstructor()) {
30  return -1 * parser::kIsConstructor;
31  }
32  if (mem.isDestructor()) {
33  return -1 * parser::kIsDestructor;
34  }
35  // Some operators are allowed, e.g. operator[].
36  //if (mem.isOperator()) {
37  // return -1 * parser::kIsOperator;
38  //}
39  if (!mem.isPublic()) {
40  return -1 * parser::kIsNotPublic;
41  }
42  if (mem.isStatic()) {
43  return -1 * parser::kIsStatic;
44  }
45  if (!mem.isConst()) {
46  return -1 * parser::kIsNotConst;
47  }
48  if (mem.name().substr(0, 2) == "__") {
50  }
51  // Functions from a base class are allowed.
52  //if (mem.declaringType() != type) {
53  //std::cerr <<
54  // "\nMETHOD OVERLOAD " <<
55  // mem.name() <<
56  // " by " <<
57  // type.qualifiedName() <<
58  // " from " <<
59  // mem.declaringType().qualifiedName() <<
60  // std::endl;
61  //return -1 * parser::kOverloaded;
62  //}
63 
64  size_t minArgs = mem.functionParameterSize(true);
65  size_t maxArgs = mem.functionParameterSize(false);
66  if ((args.size() < minArgs) || (args.size() > maxArgs)) {
68  }
69  //std::cerr <<
70  // "\nMETHOD " <<
71  // mem.name() <<
72  // " of " <<
73  // mem.declaringType().name() <<
74  // ", min #args = " <<
75  // minArgs <<
76  // ", max #args = " <<
77  // maxArgs <<
78  // ", args = " <<
79  // args.size() <<
80  // std::endl;
81  if (!args.empty()) {
82  std::vector<AnyMethodArgument> tmpFixups;
83  size_t i = 0;
84  for (auto const& param : mem) {
86  std::pair<AnyMethodArgument, int> fixup = std::visit(reco::parser::AnyMethodArgumentFixup(parameter), args[i]);
87  //std::cerr <<
88  // "\t ARG " <<
89  // i <<
90  // " type is " <<
91  // parameter.name() <<
92  // " conversion = " <<
93  // fixup.second <<
94  // std::endl;
95  if (fixup.second >= 0) {
96  tmpFixups.push_back(fixup.first);
97  casts += fixup.second;
98  } else {
99  return -1 * parser::kWrongArgumentType;
100  }
101  if (++i == args.size()) {
102  break;
103  }
104  }
105  fixuppedArgs.swap(tmpFixups);
106  }
107  //std::cerr <<
108  // "\nMETHOD " <<
109  // mem.name() <<
110  // " of " <<
111  // mem.declaringType().name() <<
112  // ", min #args = " <<
113  // minArgs <<
114  // ", max #args = " <<
115  // maxArgs <<
116  // ", args = " <<
117  // args.size() <<
118  // " fixupped args = " <<
119  // fixuppedArgs.size() <<
120  // "(" << casts <<
121  // " implicit casts)" <<
122  // std::endl;
123  return casts;
124  }
125 
126  typedef std::pair<int, edm::FunctionWithDict> OK;
127 
128  bool nCasts(const OK& a, const OK& b) { return a.first < b.first; }
129 
130  std::pair<edm::FunctionWithDict, bool> findMethod(const edm::TypeWithDict& t, /*class=in*/
131  const std::string& name, /*function member name=in*/
132  const std::vector<AnyMethodArgument>& args, /*args=in*/
133  std::vector<AnyMethodArgument>& fixuppedArgs, /*args=out*/
134  const char* iIterator, /*???=out*/
135  int& oError) /*err code=out*/
136  {
137  oError = parser::kNameDoesNotExist;
139  if (!bool(type)) {
140  throw parser::Exception(iIterator) << "No dictionary for class \"" << type.name() << "\".";
141  }
142  while (type.isPointer() || type.isReference()) {
143  type = type.toType();
144  }
145  while (type.isTypedef()) {
146  edm::TypeWithDict theType = type.finalType();
147  if (theType == type) {
148  break;
149  }
150  type = theType;
151  }
152  // strip const, volatile, c++ ref, ..
153  type = type.stripConstRef();
154  // Create our return value.
155  std::pair<edm::FunctionWithDict, bool> mem;
156  //FIXME: We must initialize mem.first!
157  mem.second = false;
158  // suitable members and number of integer->real casts required to get them
159  std::vector<std::pair<int, edm::FunctionWithDict> > oks;
160  std::string theArgs;
161  for (auto const& item : args) {
162  if (!theArgs.empty()) {
163  theArgs += ',';
164  }
165  theArgs += edm::TypeID(std::visit([](auto& variant) -> const std::type_info& { return typeid(variant); }, item))
166  .className();
167  }
168  edm::FunctionWithDict f = type.functionMemberByName(name, theArgs, true);
169  if (bool(f)) {
170  int casts = checkMethod(f, type, args, fixuppedArgs);
171  if (casts > -1) {
172  oks.push_back(std::make_pair(casts, f));
173  } else {
174  oError = -1 * casts;
175  //is this a show stopper error?
176  if (fatalErrorCondition(oError)) {
177  return mem;
178  }
179  }
180  } else {
182  for (auto const& F : functions) {
183  if (std::string(F->GetName()) != name) {
184  continue;
185  }
187  int casts = checkMethod(f, type, args, fixuppedArgs);
188  if (casts > -1) {
189  oks.push_back(std::make_pair(casts, f));
190  } else {
191  oError = -1 * casts;
192  //is this a show stopper error?
193  if (fatalErrorCondition(oError)) {
194  return mem;
195  }
196  }
197  }
198  }
199  //std::cout << "At base scope (type " << (type.name()) << ") found " <<
200  // oks.size() << " methods." << std::endl;
201  // found at least one method
202  if (!oks.empty()) {
203  if (oks.size() > 1) {
204  // sort by number of conversions needed
205  sort(oks.begin(), oks.end(), nCasts);
206  if (oks[0].first == oks[1].first) { // two methods with same ambiguity
207  throw parser::Exception(iIterator)
208  << "Can't resolve method \"" << name << "\" for class \"" << type.name() << "\", the two candidates "
209  << oks[0].second.name() << " and " << oks[1].second.name()
210  << " require the same number of integer->real conversions (" << oks[0].first << ").";
211  }
212  // We must fixup the args again, as both good methods
213  // have pushed them on fixuppedArgs.
214  fixuppedArgs.clear();
215  checkMethod(oks.front().second, type, args, fixuppedArgs);
216  }
217  mem.first = oks.front().second;
218  }
219  // if nothing was found, look in parent scopes without
220  // checking for cross-scope overloading, as it is not
221  // allowed
222  int baseError = parser::kNameDoesNotExist;
223  if (!bool(mem.first)) {
224  edm::TypeBases bases(type);
225  for (auto const& B : bases) {
226  mem = findMethod(edm::BaseWithDict(B).typeOf(), name, args, fixuppedArgs, iIterator, baseError);
227  if (bool(mem.first)) {
228  break;
229  }
230  if (fatalErrorCondition(baseError)) {
231  oError = baseError;
232  return mem;
233  }
234  }
235  }
236  // otherwise see if this object is just a Ref or Ptr and we should pop it out
237  if (!bool(mem.first)) {
238  // check for edm::Ref or edm::RefToBase or edm::Ptr
239  if (type.isTemplateInstance()) {
240  std::string name = type.templateName();
241  if (!name.compare("edm::Ref") || !name.compare("edm::RefToBase") || !name.compare("edm::Ptr")) {
242  // in this case i think 'get' should be taken with no arguments!
243  std::vector<AnyMethodArgument> empty;
244  std::vector<AnyMethodArgument> empty2;
245  int error = 0;
246  mem = findMethod(type, "get", empty, empty2, iIterator, error);
247  if (!bool(mem.first)) {
248  throw parser::Exception(iIterator) << "No member \"get\" in reference of type \"" << type.name() << "\".";
249  }
250  mem.second = true;
251  }
252  }
253  }
254  //if (!bool(mem.first)) {
255  // throw edm::Exception(edm::errors::Configuration) << "member \""" <<
256  // name << "\"" not found in class \"" << type.name() << "\"";
257  //}
258  if (bool(mem.first)) {
259  oError = parser::kNoError;
260  } else {
261  // use error from base check if we never found function in primary class
262  if (oError == parser::kNameDoesNotExist) {
263  oError = baseError;
264  }
265  }
266  return mem;
267  }
268 
269 } // namespace reco
writedatasetfile.args
args
Definition: writedatasetfile.py:18
mps_fire.i
i
Definition: mps_fire.py:428
pfMETsysShiftCorrections_cfi.parameter
parameter
Definition: pfMETsysShiftCorrections_cfi.py:118
reco::parser::kIsNotPublic
Definition: ErrorCodes.h:33
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
ErrorCodes.h
reco::parser::kNameDoesNotExist
Definition: ErrorCodes.h:32
BaseWithDict.h
reco::parser::kIsOperator
Definition: ErrorCodes.h:39
reco::nCasts
bool nCasts(const OK &a, const OK &b)
Definition: findMethod.cc:128
TypeID.h
TypeWithDict.h
reco
fixed size matrix
Definition: AlignmentAlgorithmBase.h:46
edm::TypeWithDict::stripConstRef
TypeWithDict & stripConstRef()
Definition: TypeWithDict.cc:254
reco::parser::AnyMethodArgument
std::conditional< matches_another_integral_type< unsigned long >::value, std::variant< int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, double, float, std::string >, std::variant< int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, unsigned long, double, float, std::string > >::type AnyMethodArgument
Definition: AnyMethodArgument.h:45
mem
uint16_t mem[nChs][nEvts]
Definition: recycleTccEmu.cc:13
relativeConstraints.error
error
Definition: relativeConstraints.py:53
reco::OK
std::pair< int, edm::FunctionWithDict > OK
Definition: findMethod.cc:126
F
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
edm::BaseWithDict
Definition: BaseWithDict.h:18
reco::parser::kIsFunctionAddedByROOT
Definition: ErrorCodes.h:36
reco::parser::AnyMethodArgumentFixup
Definition: AnyMethodArgument.h:47
reco::parser::kIsDestructor
Definition: ErrorCodes.h:38
reco::parser::kIsNotConst
Definition: ErrorCodes.h:35
Exception.h
AnyMethodArgument
reco::parser::AnyMethodArgument AnyMethodArgument
Definition: findMethod.cc:12
b
double b
Definition: hdecay.h:118
first
auto first
Definition: CAHitNtupletGeneratorKernelsImpl.h:125
edm::TypeWithDict::finalType
TypeWithDict finalType() const
Definition: TypeWithDict.cc:623
reco::findMethod
std::pair< edm::FunctionWithDict, bool > findMethod(const edm::TypeWithDict &t, const std::string &name, const std::vector< AnyMethodArgument > &args, std::vector< AnyMethodArgument > &fixuppedArgs, const char *iIterator, int &oError)
Definition: findMethod.cc:130
edm::TypeWithDict
Definition: TypeWithDict.h:38
reco::parser::kNoError
Definition: ErrorCodes.h:31
a
double a
Definition: hdecay.h:119
type
type
Definition: SiPixelVCal_PayloadInspector.cc:39
reco::checkMethod
int checkMethod(const edm::FunctionWithDict &mem, const edm::TypeWithDict &type, const std::vector< AnyMethodArgument > &args, std::vector< AnyMethodArgument > &fixuppedArgs)
Definition: findMethod.cc:24
jetUpdater_cfi.sort
sort
Definition: jetUpdater_cfi.py:29
gainCalibHelper::gainCalibPI::type
type
Definition: SiPixelGainCalibHelper.h:40
B2GTnPMonitor_cfi.item
item
Definition: B2GTnPMonitor_cfi.py:147
submitPVResolutionJobs.err
err
Definition: submitPVResolutionJobs.py:85
stringResolutionProvider_cfi.functions
functions
Definition: stringResolutionProvider_cfi.py:7
AlCaHLTBitMon_QueryRunRegistry.string
string string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
edm::TypeID::className
std::string const & className() const
Definition: TypeID.cc:40
fatalErrorCondition
static bool fatalErrorCondition(const int err)
Definition: findMethod.cc:16
TtFullHadDaughter::B
static const std::string B
Definition: TtFullHadronicEvent.h:9
reco::parser::kIsStatic
Definition: ErrorCodes.h:34
edm::TypeID
Definition: TypeID.h:22
edm::FunctionWithDict
Definition: FunctionWithDict.h:27
relativeConstraints.empty
bool empty
Definition: relativeConstraints.py:46
Exception
Definition: hltDiff.cc:245
Skims_PA_cff.name
name
Definition: Skims_PA_cff.py:17
reco::parser::kIsConstructor
Definition: ErrorCodes.h:37
reco::parser::kWrongNumberOfArguments
Definition: ErrorCodes.h:40
findMethod.h
edm::TypeBases
Definition: TypeWithDict.h:153
submitPVValidationJobs.t
string t
Definition: submitPVValidationJobs.py:644
reco::parser::kWrongArgumentType
Definition: ErrorCodes.h:41
edm::TypeFunctionMembers
Definition: TypeWithDict.h:175