CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_9_patch3/src/CommonTools/Utils/src/MethodSetter.cc

Go to the documentation of this file.
00001 #include "CommonTools/Utils/src/MethodSetter.h"
00002 #include "CommonTools/Utils/src/returnType.h"
00003 #include "CommonTools/Utils/src/findMethod.h"
00004 #include "CommonTools/Utils/src/findDataMember.h"
00005 #include "CommonTools/Utils/src/ErrorCodes.h"
00006 #include "CommonTools/Utils/interface/Exception.h"
00007 #include <string>
00008 using namespace reco::parser;
00009 using namespace std;
00010 using namespace Reflex;
00011 
00012 void MethodSetter::operator()(const char * begin, const char * end) const {
00013   string name(begin, end);
00014   string::size_type parenthesis = name.find_first_of('(');
00015   if (*begin == '[' || *begin == '(') {
00016     name.insert(0, "operator..");           // operator..[arg];
00017     parenthesis = 10;                       //           ^--- idx = 10
00018     name[8] = *begin;                       // operator[.[arg];
00019     name[9] =  name[name.size()-1];         // operator[][arg];
00020     name[10] = '(';                         // operator[](arg];
00021     name[name.size()-1] = ')';              // operator[](arg);    
00022     // we don't actually need the last two, but just for extra care
00023     //std::cout << "Transformed {" << string(begin,end) << "} into {"<< name <<"}" << std::endl;
00024   }
00025   std::vector<AnyMethodArgument> args;
00026   if(parenthesis != string::npos) {
00027     name.erase(parenthesis, name.size());
00028     if(intStack_.size()==0)
00029       throw Exception(begin)
00030         << "expected method argument, but non given.";    
00031     for(vector<AnyMethodArgument>::const_iterator i = intStack_.begin(); i != intStack_.end(); ++i)
00032       args.push_back(*i);
00033     intStack_.clear();
00034   }
00035   string::size_type endOfExpr = name.find_last_of(' ');
00036   if(endOfExpr != string::npos)
00037     name.erase(endOfExpr, name.size());
00038   //std::cerr << "Pushing [" << name << "] with " << args.size() << " args " << (lazy_ ? "(lazy)" : "(immediate)") << std::endl;
00039   if (lazy_) lazyMethStack_.push_back(LazyInvoker(name, args)); // for lazy parsing we just push method name and arguments
00040   else push(name, args,begin);  // otherwise we really have to resolve the method
00041   //std::cerr << "Pushed [" << name << "] with " << args.size() << " args " << (lazy_ ? "(lazy)" : "(immediate)") << std::endl;
00042 }
00043 
00044 bool MethodSetter::push(const string & name, const vector<AnyMethodArgument> & args, const char* begin,bool deep) const {
00045   Type type = typeStack_.back();
00046   vector<AnyMethodArgument> fixups;
00047   int error;
00048   pair<Member, bool> mem = reco::findMethod(type, name, args, fixups,begin,error);
00049   if(mem.first) {
00050      Type retType = reco::returnType(mem.first);
00051      if(!retType) {
00052         throw Exception(begin)
00053         << "member \"" << mem.first.Name() << "\" return type is invalid:\n" 
00054         << "  member type: \"" <<  mem.first.TypeOf().Name() << "\"\n"
00055         << "  return type: \"" << mem.first.TypeOf().ReturnType().Name() << "\"\n";
00056         
00057      }
00058      typeStack_.push_back(retType);
00059      // check for edm::Ref, edm::RefToBase, edm::Ptr
00060      if(mem.second) {
00061         //std::cout << "Mem.second, so book " << mem.first.Name() << " without fixups." << std::endl;
00062         methStack_.push_back(MethodInvoker(mem.first));
00063         if (deep) push(name, args,begin); // note: we have not found the method, so we have not fixupped the arguments
00064         else return false;
00065       } else {
00066         //std::cout << "Not mem.second, so book " << mem.first.Name() << " with #args = " << fixups.size() << std::endl;
00067         methStack_.push_back(MethodInvoker(mem.first, fixups));
00068       }
00069   } else {
00070      if(error != reco::parser::kNameDoesNotExist) {
00071         switch(error) {
00072            case reco::parser::kIsNotPublic:
00073             throw Exception(begin)
00074               << "method named \"" << name << "\" for type \"" 
00075               <<type.Name() << "\" is not publically accessible.";
00076             break;
00077            case reco::parser::kIsStatic:
00078              throw Exception(begin)
00079                << "method named \"" << name << "\" for type \"" 
00080                <<type.Name() << "\" is static.";
00081              break;
00082            case reco::parser::kIsNotConst:
00083               throw Exception(begin)
00084                 << "method named \"" << name << "\" for type \"" 
00085                 <<type.Name() << "\" is not const.";
00086               break;
00087            case reco::parser::kWrongNumberOfArguments:
00088                throw Exception(begin)
00089                  << "method named \"" << name << "\" for type \"" 
00090                  <<type.Name() << "\" was passed the wrong number of arguments.";
00091                break;
00092            case reco::parser::kWrongArgumentType:
00093                throw Exception(begin)
00094                      << "method named \"" << name << "\" for type \"" 
00095                      <<type.Name() << "\" was passed the wrong types of arguments.";
00096                break;
00097            default:  
00098             throw Exception(begin)
00099              << "method named \"" << name << "\" for type \"" 
00100              <<type.Name() << "\" is not usable in this context.";
00101         }
00102      }
00103      //see if it is a member data
00104      int error;
00105      Member member = reco::findDataMember(type,name,error);
00106      if(!member) {
00107         switch(error) {
00108            case reco::parser::kNameDoesNotExist:
00109             throw Exception(begin)
00110                << "no method or data member named \"" << name << "\" found for type \"" 
00111                <<type.Name() << "\"";
00112             break;
00113            case reco::parser::kIsNotPublic:
00114             throw Exception(begin)
00115               << "data member named \"" << name << "\" for type \"" 
00116               <<type.Name() << "\" is not publically accessible.";
00117             break;
00118            default:
00119            throw Exception(begin)
00120              << "data member named \"" << name << "\" for type \"" 
00121              <<type.Name() << "\" is not usable in this context.";
00122            break;
00123         }
00124      }
00125      typeStack_.push_back(member.TypeOf());
00126      methStack_.push_back(MethodInvoker(member));
00127   }
00128   return true;
00129 }
00130