CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
findMethod.cc
Go to the documentation of this file.
4 #include "Reflex/Base.h"
5 #include "Reflex/TypeTemplate.h"
6 
7 using namespace ROOT::Reflex;
8 using namespace std;
10 
11 //Checks for errors which show we got the correct function be we just can't use it
12 static bool fatalErrorCondition(int iError)
13 {
14  return (reco::parser::kIsNotPublic==iError ||
15  reco::parser::kIsStatic==iError ||
20 
21 }
22 namespace reco {
23  int checkMethod(const ROOT::Reflex::Member & mem,
24  const ROOT::Reflex::Type & type,
25  const std::vector<AnyMethodArgument> &args, std::vector<AnyMethodArgument> &fixuppedArgs) {
26  int casts = 0;
27  if (mem.IsConstructor()) return -1*parser::kIsConstructor;
28  if (mem.IsDestructor()) return -1*parser::kIsDestructor;
29  //if (mem.IsOperator()) return -1*parser::kIsOperator; // no, some operators are allowed, e.g. operator[]
30  if (! mem.IsPublic()) return -1*parser::kIsNotPublic;
31  if (mem.IsStatic()) return -1*parser::kIsStatic;
32  if ( ! mem.TypeOf().IsConst() ) return -1*parser::kIsNotConst;
33  if (mem.Name().substr(0, 2) == "__") return -1*parser::kIsFunctionAddedByROOT;
34  if (mem.DeclaringType().Id() != type.Id()) {
35  /*std::cerr << "\nMETHOD OVERLOAD " << mem.Name() <<
36  " by " << type.Name(QUALITIED|SCOPED) <<
37  " from " << mem.DeclaringType().Name(QUALIFIED|SCOPED) << std::endl; */
38  return -1*parser::kOverloaded;
39  }
40  size_t minArgs = mem.FunctionParameterSize(true), maxArgs = mem.FunctionParameterSize(false);
41  if ((args.size() < minArgs) || (args.size() > maxArgs)) return -1*parser::kWrongNumberOfArguments;
42  /*std::cerr << "\nMETHOD " << mem.Name() << " of " << mem.DeclaringType().Name()
43  << ", min #args = " << minArgs << ", max #args = " << maxArgs
44  << ", args = " << args.size() << std::endl;*/
45  if (!args.empty()) {
46  Type t = mem.TypeOf();
47  std::vector<AnyMethodArgument> tmpFixups;
48  for (size_t i = 0; i < args.size(); ++i) {
49  std::pair<AnyMethodArgument,int> fixup = boost::apply_visitor( reco::parser::AnyMethodArgumentFixup(t.FunctionParameterAt(i)), args[i] );
50  //std::cerr << "\t ARG " << i << " type is " << t.FunctionParameterAt(i).Name() << " conversion = " << fixup.second << std::endl;
51  if (fixup.second >= 0) {
52  tmpFixups.push_back(fixup.first);
53  casts += fixup.second;
54  } else {
56  }
57  }
58  fixuppedArgs.swap(tmpFixups);
59  }
60  /*std::cerr << "\nMETHOD " << mem.Name() << " of " << mem.DeclaringType().Name()
61  << ", min #args = " << minArgs << ", max #args = " << maxArgs
62  << ", args = " << args.size() << " fixupped args = " << fixuppedArgs.size() << "(" << casts << " implicit casts)" << std::endl; */
63  return casts;
64  }
65 
66  pair<Member, bool> findMethod(const Type & t,
67  const string & name,
68  const std::vector<AnyMethodArgument> &args,
69  std::vector<AnyMethodArgument> &fixuppedArgs,
70  const char* iIterator,
71  int& oError) {
73  Type type = t;
74  if (! type)
75  throw parser::Exception(iIterator)
76  << "No dictionary for class \"" << type.Name() << "\".";
77  while(type.IsPointer() || type.IsTypedef()) type = type.ToType();
78  type = Type(type,0); // strip const, volatile, c++ ref, ..
79 
80  pair<Member, bool> mem; mem.second = false;
81 
82  // suitable members and number of integer->real casts required to get them
83  vector<pair<int,Member> > oks;
84 
85  // first look in base scope
86  for(Member_Iterator m = type.FunctionMember_Begin(); m != type.FunctionMember_End(); ++m ) {
87  if(m->Name()==name) {
88  int casts = checkMethod(*m, type, args, fixuppedArgs);
89  if (casts > -1) {
90  oks.push_back( make_pair(casts,*m) );
91  } else {
92  oError = -1*casts;
93  //is this a show stopper error?
94  if(fatalErrorCondition(oError)) {
95  return mem;
96  }
97  }
98  }
99  }
100  //std::cout << "At base scope (type " << (type.Name()) << ") found " << oks.size() << " methods." << std::endl;
101  // found at least one method
102  if (!oks.empty()) {
103  if (oks.size() > 1) {
104  // sort by number of conversiosns needed
105  sort(oks.begin(), oks.end());
106 
107  if (oks[0].first == oks[1].first) { // two methods with same ambiguity
108  throw parser::Exception(iIterator)
109  << "Can't resolve method \"" << name << "\" for class \"" << type.Name() << "\", the two candidates "
110  << oks[0].second.Name() << " and " << oks[1].second.Name()
111  << " require the same number of integer->real conversions (" << oks[0].first << ").";
112  }
113 
114  // I should fixup again the args, as both good methods have pushed them on fixuppedArgs
115  fixuppedArgs.clear();
116  checkMethod(oks.front().second, type, args, fixuppedArgs);
117  }
118  mem.first = oks.front().second;
119  }
120 
121  // if nothing was found, look in parent scopes (without checking for cross-scope overloading, as it's not allowed)
122  int baseError=parser::kNameDoesNotExist;
123  if(! mem.first) {
124  for(Base_Iterator b = type.Base_Begin(); b != type.Base_End(); ++ b) {
125  if((mem = findMethod(b->ToType(), name, args, fixuppedArgs,iIterator,baseError)).first) break;
126  if(fatalErrorCondition(baseError)) {
127  oError = baseError;
128  return mem;
129  }
130  }
131  }
132 
133  // otherwise see if this object is just a Ref or Ptr and we should pop it out
134  if(!mem.first) {
135  // check for edm::Ref or edm::RefToBase or edm::Ptr
136  // std::cout << "Mem.first is null, so looking for templates from type " << type.Name() << std::endl;
137  if(type.IsTemplateInstance()) {
138  TypeTemplate templ = type.TemplateFamily();
139  std::string name = templ.Name();
140  if(name.compare("Ref") == 0 ||
141  name.compare("RefToBase") == 0 ||
142  name.compare("Ptr") == 0) {
143  // in this case i think 'get' should be taken with no arguments!
144  std::vector<AnyMethodArgument> empty, empty2;
145  int error;
146  mem = findMethod(type, "get", empty, empty2,iIterator,error);
147  if(!mem.first) {
148  throw parser::Exception(iIterator)
149  << "No member \"get\" in reference of type \"" << type.Name() << "\".";
150  }
151  mem.second = true;
152  }
153  }
154  }
155  /*
156  if(!mem.first) {
157  throw edm::Exception(edm::errors::Configuration)
158  << "member \""" << name << "\"" not found in class \"" << type.Name() << "\"";
159  }
160  */
161  if(mem.first) {
162  oError = parser::kNoError;
163  } else {
164  //use error from base check if we never found function in primary class
165  if(oError == parser::kNameDoesNotExist) {
166  oError = baseError;
167  }
168  }
169  return mem;
170  }
171 }
type
Definition: HCALResponse.h:22
int i
Definition: DBlmapReader.cc:9
int checkMethod(const ROOT::Reflex::Member &mem, const ROOT::Reflex::Type &type, const std::vector< AnyMethodArgument > &args, std::vector< AnyMethodArgument > &fixuppedArgs)
Definition: findMethod.cc:23
static bool fatalErrorCondition(int iError)
Definition: findMethod.cc:12
uint16_t mem[nChs][nEvts]
bool first
Definition: L1TdeRCT.cc:79
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
pair< Member, bool > findMethod(const Type &t, const string &name, const std::vector< AnyMethodArgument > &args, std::vector< AnyMethodArgument > &fixuppedArgs, const char *iIterator, int &oError)
Definition: findMethod.cc:66
double b
Definition: hdecay.h:120
dictionary args