From: Ilya Maykov Date: Thu, 1 Mar 2012 05:56:39 +0000 (+0000) Subject: THRIFT-481: indentation of ruby classes is off by a few X-Git-Tag: 0.9.1~433 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=9be7b3886027509c8c68f79fd8ac60c0005d09e2;p=common%2Fthrift.git THRIFT-481: indentation of ruby classes is off by a few Compiler: Ruby Patch: Ilya Maykov Fixed indentation of gen-rb files by wrapping each file output stream in a class that keeps track of the indent level instead of using the global indent. git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1295423 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/compiler/cpp/src/generate/t_rb_generator.cc b/compiler/cpp/src/generate/t_rb_generator.cc index a46dfe33..94718602 100644 --- a/compiler/cpp/src/generate/t_rb_generator.cc +++ b/compiler/cpp/src/generate/t_rb_generator.cc @@ -38,6 +38,26 @@ using namespace std; +/** + * A subclass of std::ofstream that includes indenting functionality. + */ +class t_rb_ofstream : public std::ofstream { + private: + int indent_; + + public: + t_rb_ofstream() : std::ofstream(), indent_(0) { } + explicit t_rb_ofstream(const char* filename, ios_base::openmode mode = ios_base::out, int indent = 0) : + std::ofstream(filename, mode), indent_(indent) { } + + t_rb_ofstream& indent() { + for (int i = 0; i < indent_; ++i) { *this << " "; } + return *this; + } + + void indent_up() { indent_++; } + void indent_down() { indent_--; } +}; /** * Ruby code generator. @@ -76,23 +96,23 @@ class t_rb_generator : public t_oop_generator { void generate_xception (t_struct* txception); void generate_service (t_service* tservice); - std::string render_const_value(t_type* type, t_const_value* value); + t_rb_ofstream& render_const_value(t_rb_ofstream& out, t_type* type, t_const_value* value); /** * Struct generation code */ - void generate_rb_struct(std::ofstream& out, t_struct* tstruct, bool is_exception); - void generate_rb_struct_required_validator(std::ofstream& out, t_struct* tstruct); - void generate_rb_union(std::ofstream& out, t_struct* tstruct, bool is_exception); - void generate_rb_union_validator(std::ofstream& out, t_struct* tstruct); + void generate_rb_struct(t_rb_ofstream& out, t_struct* tstruct, bool is_exception); + void generate_rb_struct_required_validator(t_rb_ofstream& out, t_struct* tstruct); + void generate_rb_union(t_rb_ofstream& out, t_struct* tstruct, bool is_exception); + void generate_rb_union_validator(t_rb_ofstream& out, t_struct* tstruct); void generate_rb_function_helpers(t_function* tfunction); - void generate_rb_simple_constructor(std::ofstream& out, t_struct* tstruct); - void generate_rb_simple_exception_constructor(std::ofstream& out, t_struct* tstruct); - void generate_field_constants (std::ofstream& out, t_struct* tstruct); - void generate_field_constructors (std::ofstream& out, t_struct* tstruct); - void generate_field_defns (std::ofstream& out, t_struct* tstruct); - void generate_field_data (std::ofstream& out, t_type* field_type, const std::string& field_name, t_const_value* field_value, bool optional); + void generate_rb_simple_constructor(t_rb_ofstream& out, t_struct* tstruct); + void generate_rb_simple_exception_constructor(t_rb_ofstream& out, t_struct* tstruct); + void generate_field_constants (t_rb_ofstream& out, t_struct* tstruct); + void generate_field_constructors (t_rb_ofstream& out, t_struct* tstruct); + void generate_field_defns (t_rb_ofstream& out, t_struct* tstruct); + void generate_field_data (t_rb_ofstream& out, t_type* field_type, const std::string& field_name, t_const_value* field_value, bool optional); /** * Service-level generation functions @@ -108,57 +128,57 @@ class t_rb_generator : public t_oop_generator { * Serialization constructs */ - void generate_deserialize_field (std::ofstream &out, + void generate_deserialize_field (t_rb_ofstream &out, t_field* tfield, std::string prefix="", bool inclass=false); - void generate_deserialize_struct (std::ofstream &out, + void generate_deserialize_struct (t_rb_ofstream &out, t_struct* tstruct, std::string prefix=""); - void generate_deserialize_container (std::ofstream &out, + void generate_deserialize_container (t_rb_ofstream &out, t_type* ttype, std::string prefix=""); - void generate_deserialize_set_element (std::ofstream &out, + void generate_deserialize_set_element (t_rb_ofstream &out, t_set* tset, std::string prefix=""); - void generate_deserialize_map_element (std::ofstream &out, + void generate_deserialize_map_element (t_rb_ofstream &out, t_map* tmap, std::string prefix=""); - void generate_deserialize_list_element (std::ofstream &out, + void generate_deserialize_list_element (t_rb_ofstream &out, t_list* tlist, std::string prefix=""); - void generate_serialize_field (std::ofstream &out, + void generate_serialize_field (t_rb_ofstream &out, t_field* tfield, std::string prefix=""); - void generate_serialize_struct (std::ofstream &out, + void generate_serialize_struct (t_rb_ofstream &out, t_struct* tstruct, std::string prefix=""); - void generate_serialize_container (std::ofstream &out, + void generate_serialize_container (t_rb_ofstream &out, t_type* ttype, std::string prefix=""); - void generate_serialize_map_element (std::ofstream &out, + void generate_serialize_map_element (t_rb_ofstream &out, t_map* tmap, std::string kiter, std::string viter); - void generate_serialize_set_element (std::ofstream &out, + void generate_serialize_set_element (t_rb_ofstream &out, t_set* tmap, std::string iter); - void generate_serialize_list_element (std::ofstream &out, + void generate_serialize_list_element (t_rb_ofstream &out, t_list* tlist, std::string iter); - void generate_rdoc (std::ofstream& out, + void generate_rdoc (t_rb_ofstream& out, t_doc* tdoc); /** @@ -198,8 +218,8 @@ class t_rb_generator : public t_oop_generator { return modules; } - void begin_namespace(std::ofstream&, std::vector); - void end_namespace(std::ofstream&, std::vector); + void begin_namespace(t_rb_ofstream&, std::vector); + void end_namespace(t_rb_ofstream&, std::vector); private: @@ -207,9 +227,9 @@ class t_rb_generator : public t_oop_generator { * File streams */ - std::ofstream f_types_; - std::ofstream f_consts_; - std::ofstream f_service_; + t_rb_ofstream f_types_; + t_rb_ofstream f_consts_; + t_rb_ofstream f_service_; /** If true, add a "require 'rubygems'" line to the top of each gen-rb file. */ bool require_rubygems_; @@ -312,9 +332,9 @@ void t_rb_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_rb_generator::generate_enum(t_enum* tenum) { - indent(f_types_) << + f_types_.indent() << "module " << capitalize(tenum->get_name()) << endl; - indent_up(); + f_types_.indent_up(); vector constants = tenum->get_constants(); vector::iterator c_iter; @@ -327,11 +347,11 @@ void t_rb_generator::generate_enum(t_enum* tenum) { string name = capitalize((*c_iter)->get_name()); generate_rdoc(f_types_, *c_iter); - indent(f_types_) << name << " = " << value << endl; + f_types_.indent() << name << " = " << value << endl; } // Create a hash mapping values back to their names (as strings) since ruby has no native enum type - indent(f_types_) << "VALUE_MAP = {"; + f_types_.indent() << "VALUE_MAP = {"; bool first = true; for(c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { // Populate the hash @@ -342,7 +362,7 @@ void t_rb_generator::generate_enum(t_enum* tenum) { f_types_ << "}" << endl; // Create a set with valid values for this enum - indent(f_types_) << "VALID_VALUES = Set.new(["; + f_types_.indent() << "VALID_VALUES = Set.new(["; first = true; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { // Populate the set @@ -351,8 +371,8 @@ void t_rb_generator::generate_enum(t_enum* tenum) { } f_types_ << "]).freeze" << endl; - indent_down(); - indent(f_types_) << + f_types_.indent_down(); + f_types_.indent() << "end" << endl << endl; } @@ -366,8 +386,8 @@ void t_rb_generator::generate_const(t_const* tconst) { name[0] = toupper(name[0]); - indent(f_consts_) << name << " = " << render_const_value(type, value); - f_consts_ << endl << endl; + f_consts_.indent() << name << " = "; + render_const_value(f_consts_, type, value) << endl << endl; } /** @@ -375,9 +395,8 @@ void t_rb_generator::generate_const(t_const* tconst) { * is NOT performed in this function as it is always run beforehand using the * validate_types method in main.cc */ -string t_rb_generator::render_const_value(t_type* type, t_const_value* value) { +t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out, t_type* type, t_const_value* value) { type = get_true_type(type); - std::ostringstream out; if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); switch (tbase) { @@ -404,10 +423,10 @@ string t_rb_generator::render_const_value(t_type* type, t_const_value* value) { throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { - indent(out) << value->get_integer(); + out.indent() << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { out << full_type_name(type) << ".new({" << endl; - indent_up(); + out.indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; const map& val = value->get_map(); @@ -422,30 +441,26 @@ string t_rb_generator::render_const_value(t_type* type, t_const_value* value) { if (field_type == NULL) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } - out << indent(); - out << render_const_value(g_type_string, v_iter->first); - out << " => "; - out << render_const_value(field_type, v_iter->second); - out << "," << endl; + out.indent(); + render_const_value(out, g_type_string, v_iter->first) << " => "; + render_const_value(out, field_type, v_iter->second) << "," << endl; } - indent_down(); - indent(out) << "})"; + out.indent_down(); + out.indent() << "})"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); out << "{" << endl; - indent_up(); + out.indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - out << indent(); - out << render_const_value(ktype, v_iter->first); - out << " => "; - out << render_const_value(vtype, v_iter->second); - out << "," << endl; + out.indent(); + render_const_value(out, ktype, v_iter->first) << " => "; + render_const_value(out, vtype, v_iter->second) << "," << endl; } - indent_down(); - indent(out) << "}"; + out.indent_down(); + out.indent() << "}"; } else if (type->is_list() || type->is_set()) { t_type* etype; if (type->is_list()) { @@ -458,24 +473,23 @@ string t_rb_generator::render_const_value(t_type* type, t_const_value* value) { } else { out << "[" << endl; } - indent_up(); + out.indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - out << indent(); - out << render_const_value(etype, *v_iter); - out << "," << endl; + out.indent(); + render_const_value(out, etype, *v_iter) << "," << endl; } - indent_down(); + out.indent_down(); if (type->is_set()) { - indent(out) << "])"; + out.indent() << "])"; } else { - indent(out) << "]"; + out.indent() << "]"; } } else { throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name(); } - return out.str(); + return out; } /** @@ -502,16 +516,16 @@ void t_rb_generator::generate_xception(t_struct* txception) { /** * Generates a ruby struct */ -void t_rb_generator::generate_rb_struct(std::ofstream& out, t_struct* tstruct, bool is_exception = false) { +void t_rb_generator::generate_rb_struct(t_rb_ofstream& out, t_struct* tstruct, bool is_exception = false) { generate_rdoc(out, tstruct); - indent(out) << "class " << type_name(tstruct); + out.indent() << "class " << type_name(tstruct); if (is_exception) { out << " < ::Thrift::Exception"; } out << endl; - indent_up(); - indent(out) << "include ::Thrift::Struct, ::Thrift::Struct_Union" << endl; + out.indent_up(); + out.indent() << "include ::Thrift::Struct, ::Thrift::Struct_Union" << endl; if (is_exception) { generate_rb_simple_exception_constructor(out, tstruct); @@ -521,23 +535,23 @@ void t_rb_generator::generate_rb_struct(std::ofstream& out, t_struct* tstruct, b generate_field_defns(out, tstruct); generate_rb_struct_required_validator(out, tstruct); - indent(out) << "::Thrift::Struct.generate_accessors self" << endl; + out.indent() << "::Thrift::Struct.generate_accessors self" << endl; - indent_down(); - indent(out) << "end" << endl << endl; + out.indent_down(); + out.indent() << "end" << endl << endl; } /** * Generates a ruby union */ -void t_rb_generator::generate_rb_union(std::ofstream& out, t_struct* tstruct, bool is_exception = false) { +void t_rb_generator::generate_rb_union(t_rb_ofstream& out, t_struct* tstruct, bool is_exception = false) { (void) is_exception; generate_rdoc(out, tstruct); - indent(out) << "class " << type_name(tstruct) << " < ::Thrift::Union" << endl; + out.indent() << "class " << type_name(tstruct) << " < ::Thrift::Union" << endl; - indent_up(); - indent(out) << "include ::Thrift::Struct_Union" << endl; + out.indent_up(); + out.indent() << "include ::Thrift::Struct_Union" << endl; generate_field_constructors(out, tstruct); @@ -545,16 +559,16 @@ void t_rb_generator::generate_rb_union(std::ofstream& out, t_struct* tstruct, bo generate_field_defns(out, tstruct); generate_rb_union_validator(out, tstruct); - indent(out) << "::Thrift::Union.generate_accessors self" << endl; + out.indent() << "::Thrift::Union.generate_accessors self" << endl; - indent_down(); - indent(out) << "end" << endl << endl; + out.indent_down(); + out.indent() << "end" << endl << endl; } -void t_rb_generator::generate_field_constructors(std::ofstream& out, t_struct* tstruct) { +void t_rb_generator::generate_field_constructors(t_rb_ofstream& out, t_struct* tstruct) { - indent(out) << "class << self" << endl; - indent_up(); + out.indent() << "class << self" << endl; + out.indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -565,18 +579,18 @@ void t_rb_generator::generate_field_constructors(std::ofstream& out, t_struct* t } std::string field_name = (*f_iter)->get_name(); - indent(out) << "def " << field_name << "(val)" << endl; - indent(out) << " " << tstruct->get_name() << ".new(:" << field_name << ", val)" << endl; - indent(out) << "end" << endl; + out.indent() << "def " << field_name << "(val)" << endl; + out.indent() << " " << tstruct->get_name() << ".new(:" << field_name << ", val)" << endl; + out.indent() << "end" << endl; } - indent_down(); - indent(out) << "end" << endl; + out.indent_down(); + out.indent() << "end" << endl; out << endl; } -void t_rb_generator::generate_rb_simple_exception_constructor(std::ofstream& out, t_struct* tstruct) { +void t_rb_generator::generate_rb_simple_exception_constructor(t_rb_ofstream& out, t_struct* tstruct) { const vector& members = tstruct->get_members(); if (members.size() == 1) { @@ -585,21 +599,21 @@ void t_rb_generator::generate_rb_simple_exception_constructor(std::ofstream& out if ((*m_iter)->get_type()->is_string()) { string name = (*m_iter)->get_name(); - indent(out) << "def initialize(message=nil)" << endl; - indent_up(); - indent(out) << "super()" << endl; - indent(out) << "self." << name << " = message" << endl; - indent_down(); - indent(out) << "end" << endl << endl; + out.indent() << "def initialize(message=nil)" << endl; + out.indent_up(); + out.indent() << "super()" << endl; + out.indent() << "self." << name << " = message" << endl; + out.indent_down(); + out.indent() << "end" << endl << endl; if (name != "message") { - indent(out) << "def message; " << name << " end" << endl << endl; + out.indent() << "def message; " << name << " end" << endl << endl; } } } } -void t_rb_generator::generate_field_constants(std::ofstream& out, t_struct* tstruct) { +void t_rb_generator::generate_field_constants(t_rb_ofstream& out, t_struct* tstruct) { const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -607,17 +621,17 @@ void t_rb_generator::generate_field_constants(std::ofstream& out, t_struct* tstr std::string field_name = (*f_iter)->get_name(); std::string cap_field_name = upcase_string(field_name); - indent(out) << cap_field_name << " = " << (*f_iter)->get_key() << endl; + out.indent() << cap_field_name << " = " << (*f_iter)->get_key() << endl; } out << endl; } -void t_rb_generator::generate_field_defns(std::ofstream& out, t_struct* tstruct) { +void t_rb_generator::generate_field_defns(t_rb_ofstream& out, t_struct* tstruct) { const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "FIELDS = {" << endl; - indent_up(); + out.indent() << "FIELDS = {" << endl; + out.indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (f_iter != fields.begin()) { out << "," << endl; @@ -626,21 +640,20 @@ void t_rb_generator::generate_field_defns(std::ofstream& out, t_struct* tstruct) // generate the field docstrings within the FIELDS constant. no real better place... generate_rdoc(out, *f_iter); - indent(out) << - upcase_string((*f_iter)->get_name()) << " => "; + out.indent() << upcase_string((*f_iter)->get_name()) << " => "; generate_field_data(out, (*f_iter)->get_type(), (*f_iter)->get_name(), (*f_iter)->get_value(), (*f_iter)->get_req() == t_field::T_OPTIONAL); } - indent_down(); + out.indent_down(); out << endl; - indent(out) << "}" << endl << endl; + out.indent() << "}" << endl << endl; - indent(out) << "def struct_fields; FIELDS; end" << endl << endl; + out.indent() << "def struct_fields; FIELDS; end" << endl << endl; } -void t_rb_generator::generate_field_data(std::ofstream& out, t_type* field_type, +void t_rb_generator::generate_field_data(t_rb_ofstream& out, t_type* field_type, const std::string& field_name = "", t_const_value* field_value = NULL, bool optional = false) { field_type = get_true_type(field_type); @@ -652,7 +665,8 @@ void t_rb_generator::generate_field_data(std::ofstream& out, t_type* field_type, } if (field_value != NULL) { - out << ", :default => " << render_const_value(field_type, field_value); + out << ", :default => "; + render_const_value(out, field_type, field_value); } if (!field_type->is_base_type()) { @@ -688,17 +702,17 @@ void t_rb_generator::generate_field_data(std::ofstream& out, t_type* field_type, out << "}"; } -void t_rb_generator::begin_namespace(std::ofstream& out, vector modules) { +void t_rb_generator::begin_namespace(t_rb_ofstream& out, vector modules) { for (vector::iterator m_iter = modules.begin(); m_iter != modules.end(); ++m_iter) { - indent(out) << "module " << *m_iter << endl; - indent_up(); + out.indent() << "module " << *m_iter << endl; + out.indent_up(); } } -void t_rb_generator::end_namespace(std::ofstream& out, vector modules) { +void t_rb_generator::end_namespace(t_rb_ofstream& out, vector modules) { for (vector::reverse_iterator m_iter = modules.rbegin(); m_iter != modules.rend(); ++m_iter) { - indent_down(); - indent(out) << "end" << endl; + out.indent_down(); + out.indent() << "end" << endl; } } @@ -726,17 +740,16 @@ void t_rb_generator::generate_service(t_service* tservice) { begin_namespace(f_service_, ruby_modules(tservice->get_program())); - indent(f_service_) << "module " << capitalize(tservice->get_name()) << endl; - indent_up(); + f_service_.indent() << "module " << capitalize(tservice->get_name()) << endl; + f_service_.indent_up(); // Generate the three main parts of the service (well, two for now in PHP) generate_service_client(tservice); generate_service_server(tservice); generate_service_helpers(tservice); - indent_down(); - indent(f_service_) << "end" << endl << - endl; + f_service_.indent_down(); + f_service_.indent() << "end" << endl << endl; end_namespace(f_service_, ruby_modules(tservice->get_program())); @@ -753,8 +766,7 @@ void t_rb_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - indent(f_service_) << - "# HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_service_.indent() << "# HELPER FUNCTIONS AND STRUCTURES" << endl << endl; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -797,12 +809,10 @@ void t_rb_generator::generate_service_client(t_service* tservice) { extends_client = " < " + extends + "::Client "; } - indent(f_service_) << - "class Client" << extends_client << endl; - indent_up(); + f_service_.indent() << "class Client" << extends_client << endl; + f_service_.indent_up(); - indent(f_service_) << - "include ::Thrift::Client" << endl << endl; + f_service_.indent() << "include ::Thrift::Client" << endl << endl; // Generate client method implementations vector functions = tservice->get_functions(); @@ -814,10 +824,9 @@ void t_rb_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - indent(f_service_) << - "def " << function_signature(*f_iter) << endl; - indent_up(); - indent(f_service_) << + f_service_.indent() << "def " << function_signature(*f_iter) << endl; + f_service_.indent_up(); + f_service_.indent() << "send_" << funname << "("; bool first = true; @@ -832,24 +841,24 @@ void t_rb_generator::generate_service_client(t_service* tservice) { f_service_ << ")" << endl; if (!(*f_iter)->is_oneway()) { - f_service_ << indent(); + f_service_.indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } f_service_ << "recv_" << funname << "()" << endl; } - indent_down(); - indent(f_service_) << "end" << endl; + f_service_.indent_down(); + f_service_.indent() << "end" << endl; f_service_ << endl; - indent(f_service_) << + f_service_.indent() << "def send_" << function_signature(*f_iter) << endl; - indent_up(); + f_service_.indent_up(); std::string argsname = capitalize((*f_iter)->get_name() + "_args"); - indent(f_service_) << "send_message('" << funname << "', " << argsname; + f_service_.indent() << "send_message('" << funname << "', " << argsname; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << ", :" << (*fld_iter)->get_name() << " => " << (*fld_iter)->get_name(); @@ -857,8 +866,8 @@ void t_rb_generator::generate_service_client(t_service* tservice) { f_service_ << ")" << endl; - indent_down(); - indent(f_service_) << "end" << endl; + f_service_.indent_down(); + f_service_.indent() << "end" << endl; if (!(*f_iter)->is_oneway()) { std::string resultname = capitalize((*f_iter)->get_name() + "_result"); @@ -868,48 +877,46 @@ void t_rb_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); // Open function - f_service_ << - endl << - indent() << "def " << function_signature(&recv_function) << endl; - indent_up(); + f_service_ << endl; + f_service_.indent() << "def " << function_signature(&recv_function) << endl; + f_service_.indent_up(); // TODO(mcslee): Validate message reply here, seq ids etc. - f_service_ << - indent() << "result = receive_message(" << resultname << ")" << endl; + f_service_.indent() << "result = receive_message(" << resultname << ")" << endl; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << - indent() << "return result.success unless result.success.nil?" << endl; + f_service_.indent() << "return result.success unless result.success.nil?" << endl; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - indent(f_service_) << + f_service_.indent() << "raise result." << (*x_iter)->get_name() << " unless result." << (*x_iter)->get_name() << ".nil?" << endl; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << + f_service_.indent() << "return" << endl; } else { - f_service_ << - indent() << "raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, '" << (*f_iter)->get_name() << " failed: unknown result')" << endl; + f_service_.indent() << + "raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, '" << + (*f_iter)->get_name() << " failed: unknown result')" << endl; } // Close function - indent_down(); - indent(f_service_) << "end" << endl << endl; + f_service_.indent_down(); + f_service_.indent() << "end" << endl << endl; } } - indent_down(); - indent(f_service_) << "end" << endl << endl; + f_service_.indent_down(); + f_service_.indent() << "end" << endl << endl; } /** @@ -930,21 +937,19 @@ void t_rb_generator::generate_service_server(t_service* tservice) { } // Generate the header portion - indent(f_service_) << + f_service_.indent() << "class Processor" << extends_processor << endl; - indent_up(); + f_service_.indent_up(); - f_service_ << - indent() << "include ::Thrift::Processor" << endl << - endl; + f_service_.indent() << "include ::Thrift::Processor" << endl << endl; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_process_function(tservice, *f_iter); } - indent_down(); - indent(f_service_) << "end" << endl << endl; + f_service_.indent_down(); + f_service_.indent() << "end" << endl << endl; } /** @@ -956,16 +961,15 @@ void t_rb_generator::generate_process_function(t_service* tservice, t_function* tfunction) { (void) tservice; // Open function - indent(f_service_) << + f_service_.indent() << "def process_" << tfunction->get_name() << "(seqid, iprot, oprot)" << endl; - indent_up(); + f_service_.indent_up(); string argsname = capitalize(tfunction->get_name()) + "_args"; string resultname = capitalize(tfunction->get_name()) + "_result"; - f_service_ << - indent() << "args = read_args(iprot, " << argsname << ")" << endl; + f_service_.indent() << "args = read_args(iprot, " << argsname << ")" << endl; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -973,15 +977,13 @@ void t_rb_generator::generate_process_function(t_service* tservice, // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << - indent() << "result = " << resultname << ".new()" << endl; + f_service_.indent() << "result = " << resultname << ".new()" << endl; } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << - indent() << "begin" << endl; - indent_up(); + f_service_.indent() << "begin" << endl; + f_service_.indent_up(); } // Generate the function call @@ -989,7 +991,7 @@ void t_rb_generator::generate_process_function(t_service* tservice, const std::vector& fields = arg_struct->get_members(); vector::const_iterator f_iter; - f_service_ << indent(); + f_service_.indent(); if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) { f_service_ << "result.success = "; } @@ -1007,35 +1009,32 @@ void t_rb_generator::generate_process_function(t_service* tservice, f_service_ << ")" << endl; if (!tfunction->is_oneway() && xceptions.size() > 0) { - indent_down(); + f_service_.indent_down(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_ << - indent() << "rescue " << full_type_name((*x_iter)->get_type()) << " => " << (*x_iter)->get_name() << endl; + f_service_.indent() << "rescue " << full_type_name((*x_iter)->get_type()) << " => " << + (*x_iter)->get_name() << endl; if (!tfunction->is_oneway()) { - indent_up(); - f_service_ << - indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() << endl; - indent_down(); + f_service_.indent_up(); + f_service_.indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() << endl; + f_service_.indent_down(); } } - indent(f_service_) << "end" << endl; + f_service_.indent() << "end" << endl; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << - indent() << "return" << endl; - indent_down(); - indent(f_service_) << "end" << endl << endl; + f_service_.indent() << "return" << endl; + f_service_.indent_down(); + f_service_.indent() << "end" << endl << endl; return; } - f_service_ << - indent() << "write_result(result, oprot, '" << tfunction->get_name() << "', seqid)" << endl; + f_service_.indent() << "write_result(result, oprot, '" << tfunction->get_name() << "', seqid)" << endl; // Close function - indent_down(); - indent(f_service_) << "end" << endl << endl; + f_service_.indent_down(); + f_service_.indent() << "end" << endl << endl; } /** @@ -1135,17 +1134,18 @@ string t_rb_generator::type_to_enum(t_type* type) { } -void t_rb_generator::generate_rdoc(std::ofstream& out, t_doc* tdoc) { +void t_rb_generator::generate_rdoc(t_rb_ofstream& out, t_doc* tdoc) { if (tdoc->has_doc()) { + out.indent(); generate_docstring_comment(out, "", "# ", tdoc->get_doc(), ""); } } -void t_rb_generator::generate_rb_struct_required_validator(std::ofstream& out, +void t_rb_generator::generate_rb_struct_required_validator(t_rb_ofstream& out, t_struct* tstruct) { - indent(out) << "def validate" << endl; - indent_up(); + out.indent() << "def validate" << endl; + out.indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1153,7 +1153,9 @@ void t_rb_generator::generate_rb_struct_required_validator(std::ofstream& out, for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = (*f_iter); if (field->get_req() == t_field::T_REQUIRED) { - indent(out) << "raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field " << field->get_name() << " is unset!')"; + out.indent() << + "raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field " << + field->get_name() << " is unset!')"; if (field->get_type()->is_bool()) { out << " if @" << field->get_name() << ".nil?"; } else { @@ -1168,41 +1170,49 @@ void t_rb_generator::generate_rb_struct_required_validator(std::ofstream& out, t_field* field = (*f_iter); if (field->get_type()->is_enum()){ - indent(out) << "unless @" << field->get_name() << ".nil? || " << full_type_name(field->get_type()) << "::VALID_VALUES.include?(@" << field->get_name() << ")" << endl; - indent_up(); - indent(out) << "raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field " << field->get_name() << "!')" << endl; - indent_down(); - indent(out) << "end" << endl; + out.indent() << "unless @" << field->get_name() << ".nil? || " << + full_type_name(field->get_type()) << "::VALID_VALUES.include?(@" << + field->get_name() << ")" << endl; + out.indent_up(); + out.indent() << + "raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field " << + field->get_name() << "!')" << endl; + out.indent_down(); + out.indent() << "end" << endl; } } - indent_down(); - indent(out) << "end" << endl << endl; + out.indent_down(); + out.indent() << "end" << endl << endl; } -void t_rb_generator::generate_rb_union_validator(std::ofstream& out, +void t_rb_generator::generate_rb_union_validator(t_rb_ofstream& out, t_struct* tstruct) { - indent(out) << "def validate" << endl; - indent_up(); + out.indent() << "def validate" << endl; + out.indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "raise(StandardError, 'Union fields are not set.') if get_set_field.nil? || get_value.nil?" << endl; + out.indent() << + "raise(StandardError, 'Union fields are not set.') if get_set_field.nil? || get_value.nil?" << endl; // if field is an enum, check that its value is valid for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { const t_field* field = (*f_iter); if (field->get_type()->is_enum()){ - indent(out) << "if get_set_field == :" << field->get_name() << endl; - indent(out) << " raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field " << field->get_name() << "!') unless " << full_type_name(field->get_type()) << "::VALID_VALUES.include?(get_value)" << endl; - indent(out) << "end" << endl; + out.indent() << "if get_set_field == :" << field->get_name() << endl; + out.indent() << + " raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field " << + field->get_name() << "!') unless " << full_type_name(field->get_type()) << + "::VALID_VALUES.include?(get_value)" << endl; + out.indent() << "end" << endl; } } - indent_down(); - indent(out) << "end" << endl << endl; + out.indent_down(); + out.indent() << "end" << endl << endl; } THRIFT_REGISTER_GENERATOR(rb, "Ruby",