File indexing completed on 2024-04-20 02:31:38
0001 #include "CommonTools/Utils/interface/parser/MethodSetter.h"
0002
0003 #include "CommonTools/Utils/interface/parser/Exception.h"
0004 #include "CommonTools/Utils/src/ErrorCodes.h"
0005 #include "CommonTools/Utils/interface/parser/MethodInvoker.h"
0006 #include "CommonTools/Utils/src/findDataMember.h"
0007 #include "CommonTools/Utils/src/findMethod.h"
0008 #include "CommonTools/Utils/interface/returnType.h"
0009
0010 #include <string>
0011
0012 using namespace reco::parser;
0013 using namespace std;
0014
0015 void MethodSetter::operator()(const char* begin, const char* end) const {
0016 string name(begin, end);
0017 string::size_type parenthesis = name.find_first_of('(');
0018 if ((*begin == '[') || (*begin == '(')) {
0019 name.insert(0, "operator..");
0020 parenthesis = 10;
0021 name[8] = *begin;
0022 name[9] = name[name.size() - 1];
0023 name[10] = '(';
0024 name[name.size() - 1] = ')';
0025
0026
0027
0028 }
0029 std::vector<AnyMethodArgument> args;
0030 if (parenthesis != string::npos) {
0031 name.erase(parenthesis, name.size());
0032 if (intStack_.empty()) {
0033 throw Exception(begin) << "expected method argument, but non given.";
0034 }
0035 for (vector<AnyMethodArgument>::const_iterator i = intStack_.begin(); i != intStack_.end(); ++i) {
0036 args.push_back(*i);
0037 }
0038 intStack_.clear();
0039 }
0040 string::size_type endOfExpr = name.find_last_of(' ');
0041 if (endOfExpr != string::npos) {
0042 name.erase(endOfExpr, name.size());
0043 }
0044
0045
0046 if (lazy_) {
0047
0048 lazyMethStack_.push_back(LazyInvoker(name, args));
0049 } else {
0050
0051 push(name, args, begin);
0052 }
0053
0054
0055 }
0056
0057 bool MethodSetter::push(const string& name, const vector<AnyMethodArgument>& args, const char* begin, bool deep) const {
0058 edm::TypeWithDict type = typeStack_.back();
0059 vector<AnyMethodArgument> fixups;
0060 int error = 0;
0061 pair<edm::FunctionWithDict, bool> mem = reco::findMethod(type, name, args, fixups, begin, error);
0062 if (bool(mem.first)) {
0063
0064 edm::TypeWithDict retType = reco::returnType(mem.first);
0065 if (!bool(retType)) {
0066
0067 throw Exception(begin) << "member \"" << mem.first.name() << "\" return type is invalid:\n"
0068 << " return type: \"" << mem.first.typeName() << "\"\n";
0069 }
0070 typeStack_.push_back(retType);
0071
0072 if (mem.second) {
0073
0074
0075
0076 methStack_.push_back(MethodInvoker(mem.first));
0077 if (!deep) {
0078 return false;
0079 }
0080
0081
0082 push(name, args, begin);
0083 } else {
0084
0085
0086
0087 methStack_.push_back(MethodInvoker(mem.first, fixups));
0088 }
0089 return true;
0090 }
0091 if (error != reco::parser::kNameDoesNotExist) {
0092
0093 switch (error) {
0094 case reco::parser::kIsNotPublic:
0095 throw Exception(begin) << "method named \"" << name << "\" for type \"" << type.name()
0096 << "\" is not publically accessible.";
0097 break;
0098 case reco::parser::kIsStatic:
0099 throw Exception(begin) << "method named \"" << name << "\" for type \"" << type.name() << "\" is static.";
0100 break;
0101 case reco::parser::kIsNotConst:
0102 throw Exception(begin) << "method named \"" << name << "\" for type \"" << type.name() << "\" is not const.";
0103 break;
0104 case reco::parser::kWrongNumberOfArguments:
0105 throw Exception(begin) << "method named \"" << name << "\" for type \"" << type.name()
0106 << "\" was passed the wrong number of arguments.";
0107 break;
0108 case reco::parser::kWrongArgumentType:
0109 throw Exception(begin) << "method named \"" << name << "\" for type \"" << type.name()
0110 << "\" was passed the wrong types of arguments.";
0111 break;
0112 default:
0113 throw Exception(begin) << "method named \"" << name << "\" for type \"" << type.name()
0114 << "\" is not usable in this context.";
0115 }
0116 }
0117
0118 error = 0;
0119 edm::MemberWithDict member(reco::findDataMember(type, name, error));
0120 if (!bool(member)) {
0121
0122 switch (error) {
0123 case reco::parser::kNameDoesNotExist: {
0124 Exception ex(begin);
0125 ex << "no method or data member named \"" << name << "\" found for type \"" << type.name() << "\"\n";
0126
0127 ex << "It has the following methods\n";
0128 edm::TypeFunctionMembers functions(type);
0129 for (auto const& f : functions) {
0130 ex << " " << f->GetName() << "\n";
0131 }
0132 ex << "and the following data members\n";
0133 edm::TypeDataMembers members(type);
0134 for (auto const& m : members) {
0135 ex << " " << m->GetName() << "\n";
0136 }
0137 throw ex;
0138 } break;
0139 case reco::parser::kIsNotPublic:
0140 throw Exception(begin) << "data member named \"" << name << "\" for type \"" << type.name()
0141 << "\" is not publically accessible.";
0142 break;
0143 default:
0144 throw Exception(begin) << "data member named \"" << name << "\" for type \"" << type.name()
0145 << "\" is not usable in this context.";
0146 break;
0147 }
0148 }
0149
0150 typeStack_.push_back(member.typeOf());
0151 methStack_.push_back(MethodInvoker(member));
0152 return true;
0153 }