THRIFT-5302 Add recursive function name uniqueness check
Patch: wangliming07 <wangliming07@58.com>
This closes #2268
diff --git a/compiler/cpp/src/thrift/parse/t_program.h b/compiler/cpp/src/thrift/parse/t_program.h
index 140dc35..b6b1332 100644
--- a/compiler/cpp/src/thrift/parse/t_program.h
+++ b/compiler/cpp/src/thrift/parse/t_program.h
@@ -112,7 +112,10 @@
objects_.push_back(tx);
xceptions_.push_back(tx);
}
- void add_service(t_service* ts) { services_.push_back(ts); }
+ void add_service(t_service* ts) {
+ ts->validate_unique_members();
+ services_.push_back(ts);
+ }
// Programs to include
std::vector<t_program*>& get_includes() { return includes_; }
diff --git a/compiler/cpp/src/thrift/parse/t_service.h b/compiler/cpp/src/thrift/parse/t_service.h
index a43a515..f405c15 100644
--- a/compiler/cpp/src/thrift/parse/t_service.h
+++ b/compiler/cpp/src/thrift/parse/t_service.h
@@ -38,15 +38,58 @@
void set_extends(t_service* extends) { extends_ = extends; }
void add_function(t_function* func) {
- std::vector<t_function*>::const_iterator iter;
- for (iter = functions_.begin(); iter != functions_.end(); ++iter) {
- if (func->get_name() == (*iter)->get_name()) {
- throw "Function " + func->get_name() + " is already defined";
- }
+ if (get_function_by_name(func->get_name()) != NULL) {
+ throw "Function " + func->get_name() + " is already defined";
}
functions_.push_back(func);
}
+ void validate_unique_members() {
+ std::vector<t_function*>::const_iterator iter;
+ for (iter = functions_.begin(); iter != functions_.end(); ++iter) {
+ // throw exception when there is a conflict of names with super class
+ if (extends_ != NULL) {
+ if (extends_->get_function_by_name((*iter)->get_name()) != NULL) {
+ throw "Function " + (*iter)->get_name() + " is already defined in service " + name_;
+ }
+ }
+ }
+ }
+
+ t_function* get_function_by_name(std::string func_name) {
+ if (extends_ != NULL) {
+ t_function* func = NULL;
+ if ((func = extends_->get_function_by_name(func_name)) != NULL) {
+ return func;
+ }
+ }
+
+ std::vector<t_function*>::const_iterator iter;
+ for (iter = functions_.begin(); iter != functions_.end(); ++iter) {
+ if ((*iter)->get_name() == func_name) {
+ return *iter;
+ }
+ }
+ return NULL;
+ }
+
+ const t_function* get_function_by_name(std::string func_name) const {
+ if (extends_ != NULL) {
+ t_function* func = NULL;
+ if ((func = extends_->get_function_by_name(func_name)) != NULL) {
+ return func;
+ }
+ }
+
+ std::vector<t_function*>::const_iterator iter;
+ for (iter = functions_.begin(); iter != functions_.end(); ++iter) {
+ if ((*iter)->get_name() == func_name) {
+ return *iter;
+ }
+ }
+ return NULL;
+ }
+
const std::vector<t_function*>& get_functions() const { return functions_; }
t_service* get_extends() { return extends_; }