CMS 3D CMS Logo

findMethod.cc
Go to the documentation of this file.
2 
8 
9 #include <cassert>
10 
12 
15 static bool fatalErrorCondition(const int err) {
19 }
20 
21 namespace reco {
22 
24  const edm::TypeWithDict& type,
25  const std::vector<AnyMethodArgument>& args,
26  std::vector<AnyMethodArgument>& fixuppedArgs) {
27  int casts = 0;
28  if (mem.isConstructor()) {
29  return -1 * parser::kIsConstructor;
30  }
31  if (mem.isDestructor()) {
32  return -1 * parser::kIsDestructor;
33  }
34  // Some operators are allowed, e.g. operator[].
35  //if (mem.isOperator()) {
36  // return -1 * parser::kIsOperator;
37  //}
38  if (!mem.isPublic()) {
39  return -1 * parser::kIsNotPublic;
40  }
41  if (mem.isStatic()) {
42  return -1 * parser::kIsStatic;
43  }
44  if (!mem.isConst()) {
45  return -1 * parser::kIsNotConst;
46  }
47  if (mem.name().substr(0, 2) == "__") {
49  }
50  // Functions from a base class are allowed.
51  //if (mem.declaringType() != type) {
52  //std::cerr <<
53  // "\nMETHOD OVERLOAD " <<
54  // mem.name() <<
55  // " by " <<
56  // type.qualifiedName() <<
57  // " from " <<
58  // mem.declaringType().qualifiedName() <<
59  // std::endl;
60  //return -1 * parser::kOverloaded;
61  //}
62 
63  size_t minArgs = mem.functionParameterSize(true);
64  size_t maxArgs = mem.functionParameterSize(false);
65  if ((args.size() < minArgs) || (args.size() > maxArgs)) {
67  }
68  //std::cerr <<
69  // "\nMETHOD " <<
70  // mem.name() <<
71  // " of " <<
72  // mem.declaringType().name() <<
73  // ", min #args = " <<
74  // minArgs <<
75  // ", max #args = " <<
76  // maxArgs <<
77  // ", args = " <<
78  // args.size() <<
79  // std::endl;
80  if (!args.empty()) {
81  std::vector<AnyMethodArgument> tmpFixups;
82  size_t i = 0;
83  for (auto const& param : mem) {
85  std::pair<AnyMethodArgument, int> fixup =
86  boost::apply_visitor(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(item.type()).className();
166  }
167  edm::FunctionWithDict f = type.functionMemberByName(name, theArgs, true);
168  if (bool(f)) {
169  int casts = checkMethod(f, type, args, fixuppedArgs);
170  if (casts > -1) {
171  oks.push_back(std::make_pair(casts, f));
172  } else {
173  oError = -1 * casts;
174  //is this a show stopper error?
175  if (fatalErrorCondition(oError)) {
176  return mem;
177  }
178  }
179  } else {
181  for (auto const& F : functions) {
182  if (std::string(F->GetName()) != name) {
183  continue;
184  }
186  int casts = checkMethod(f, type, args, fixuppedArgs);
187  if (casts > -1) {
188  oks.push_back(std::make_pair(casts, f));
189  } else {
190  oError = -1 * casts;
191  //is this a show stopper error?
192  if (fatalErrorCondition(oError)) {
193  return mem;
194  }
195  }
196  }
197  }
198  //std::cout << "At base scope (type " << (type.name()) << ") found " <<
199  // oks.size() << " methods." << std::endl;
200  // found at least one method
201  if (!oks.empty()) {
202  if (oks.size() > 1) {
203  // sort by number of conversions needed
204  sort(oks.begin(), oks.end(), nCasts);
205  if (oks[0].first == oks[1].first) { // two methods with same ambiguity
206  throw parser::Exception(iIterator)
207  << "Can't resolve method \"" << name << "\" for class \"" << type.name() << "\", the two candidates "
208  << oks[0].second.name() << " and " << oks[1].second.name()
209  << " require the same number of integer->real conversions (" << oks[0].first << ").";
210  }
211  // We must fixup the args again, as both good methods
212  // have pushed them on fixuppedArgs.
213  fixuppedArgs.clear();
214  checkMethod(oks.front().second, type, args, fixuppedArgs);
215  }
216  mem.first = oks.front().second;
217  }
218  // if nothing was found, look in parent scopes without
219  // checking for cross-scope overloading, as it is not
220  // allowed
221  int baseError = parser::kNameDoesNotExist;
222  if (!bool(mem.first)) {
223  edm::TypeBases bases(type);
224  for (auto const& B : bases) {
225  mem = findMethod(edm::BaseWithDict(B).typeOf(), name, args, fixuppedArgs, iIterator, baseError);
226  if (bool(mem.first)) {
227  break;
228  }
229  if (fatalErrorCondition(baseError)) {
230  oError = baseError;
231  return mem;
232  }
233  }
234  }
235  // otherwise see if this object is just a Ref or Ptr and we should pop it out
236  if (!bool(mem.first)) {
237  // check for edm::Ref or edm::RefToBase or edm::Ptr
238  if (type.isTemplateInstance()) {
239  std::string name = type.templateName();
240  if (!name.compare("edm::Ref") || !name.compare("edm::RefToBase") || !name.compare("edm::Ptr")) {
241  // in this case i think 'get' should be taken with no arguments!
242  std::vector<AnyMethodArgument> empty;
243  std::vector<AnyMethodArgument> empty2;
244  int error = 0;
245  mem = findMethod(type, "get", empty, empty2, iIterator, error);
246  if (!bool(mem.first)) {
247  throw parser::Exception(iIterator) << "No member \"get\" in reference of type \"" << type.name() << "\".";
248  }
249  mem.second = true;
250  }
251  }
252  }
253  //if (!bool(mem.first)) {
254  // throw edm::Exception(edm::errors::Configuration) << "member \""" <<
255  // name << "\"" not found in class \"" << type.name() << "\"";
256  //}
257  if (bool(mem.first)) {
258  oError = parser::kNoError;
259  } else {
260  // use error from base check if we never found function in primary class
261  if (oError == parser::kNameDoesNotExist) {
262  oError = baseError;
263  }
264  }
265  return mem;
266  }
267 
268 } // namespace reco
writedatasetfile.args
args
Definition: writedatasetfile.py:18
mps_fire.i
i
Definition: mps_fire.py:355
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:45
edm::TypeWithDict::stripConstRef
TypeWithDict & stripConstRef()
Definition: TypeWithDict.cc:254
mem
uint16_t mem[nChs][nEvts]
Definition: recycleTccEmu.cc:13
relativeConstraints.error
error
Definition: relativeConstraints.py:53
dqmdumpme.first
first
Definition: dqmdumpme.py:55
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:51
parameter
Definition: vlib.h:168
reco::parser::kIsDestructor
Definition: ErrorCodes.h:38
reco::parser::kIsNotConst
Definition: ErrorCodes.h:35
Exception.h
AnyMethodArgument
reco::parser::AnyMethodArgument AnyMethodArgument
Definition: findMethod.cc:11
OrderedSet.t
t
Definition: OrderedSet.py:90
b
double b
Definition: hdecay.h:118
reco::parser::AnyMethodArgument
boost::mpl::if_< matches_another_integral_type< unsigned long >, boost::variant< int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, double, float, std::string >, boost::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:49
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
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
edm::TypeWithDict
Definition: TypeWithDict.h:38
reco::parser::kNoError
Definition: ErrorCodes.h:31
a
double a
Definition: hdecay.h:119
runTheMatrix.err
err
Definition: runTheMatrix.py:288
reco::checkMethod
int checkMethod(const edm::FunctionWithDict &mem, const edm::TypeWithDict &type, const std::vector< AnyMethodArgument > &args, std::vector< AnyMethodArgument > &fixuppedArgs)
Definition: findMethod.cc:23
B2GTnPMonitor_cfi.item
item
Definition: B2GTnPMonitor_cfi.py:147
stringResolutionProvider_cfi.functions
functions
Definition: stringResolutionProvider_cfi.py:7
fatalErrorCondition
static bool fatalErrorCondition(const int err)
Definition: findMethod.cc:15
TtFullHadDaughter::B
static const std::string B
Definition: TtFullHadronicEvent.h:9
reco::parser::kIsStatic
Definition: ErrorCodes.h:34
edm::TypeID
Definition: TypeID.h:22
type
type
Definition: HCALResponse.h:21
edm::FunctionWithDict
Definition: FunctionWithDict.h:27
relativeConstraints.empty
bool empty
Definition: relativeConstraints.py:46
Exception
Definition: hltDiff.cc:246
Skims_PA_cff.name
name
Definition: Skims_PA_cff.py:17
reco::parser::kIsConstructor
Definition: ErrorCodes.h:37
className
std::string className(const T &t)
Definition: ClassName.h:31
reco::parser::kWrongNumberOfArguments
Definition: ErrorCodes.h:40
findMethod.h
edm::TypeBases
Definition: TypeWithDict.h:153
reco::parser::kWrongArgumentType
Definition: ErrorCodes.h:41
edm::TypeFunctionMembers
Definition: TypeWithDict.h:175