Author: bryanduxbury
Date: Tue Jan 11 19:21:51 2011
New Revision: 1057810
URL: http://svn.apache.org/viewvc?rev=1057810&view=rev
Log:
merge in THRIFT-1033 from trunk
Added:
thrift/branches/0.6.x/lib/nodejs/
- copied from r1056613, thrift/trunk/lib/nodejs/
thrift/branches/0.6.x/lib/nodejs/README.md
- copied unchanged from r1056613, thrift/trunk/lib/nodejs/README.md
thrift/branches/0.6.x/lib/nodejs/examples/
- copied from r1056613, thrift/trunk/lib/nodejs/examples/
thrift/branches/0.6.x/lib/nodejs/examples/Makefile
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/examples/Makefile
thrift/branches/0.6.x/lib/nodejs/examples/README.md
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/examples/README.md
thrift/branches/0.6.x/lib/nodejs/examples/client.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/examples/client.js
thrift/branches/0.6.x/lib/nodejs/examples/server.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/examples/server.js
thrift/branches/0.6.x/lib/nodejs/examples/user.thrift
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/examples/user.thrift
thrift/branches/0.6.x/lib/nodejs/lib/
- copied from r1056613, thrift/trunk/lib/nodejs/lib/
thrift/branches/0.6.x/lib/nodejs/lib/thrift/
- copied from r1056613, thrift/trunk/lib/nodejs/lib/thrift/
thrift/branches/0.6.x/lib/nodejs/lib/thrift/binary_parser.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/lib/thrift/binary_parser.js
thrift/branches/0.6.x/lib/nodejs/lib/thrift/connection.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/lib/thrift/connection.js
thrift/branches/0.6.x/lib/nodejs/lib/thrift/index.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/lib/thrift/index.js
thrift/branches/0.6.x/lib/nodejs/lib/thrift/protocol.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/lib/thrift/protocol.js
thrift/branches/0.6.x/lib/nodejs/lib/thrift/server.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/lib/thrift/server.js
thrift/branches/0.6.x/lib/nodejs/lib/thrift/thrift.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/lib/thrift/thrift.js
thrift/branches/0.6.x/lib/nodejs/lib/thrift/transport.js
- copied unchanged from r1056613,
thrift/trunk/lib/nodejs/lib/thrift/transport.js
thrift/branches/0.6.x/lib/nodejs/package.json
- copied unchanged from r1056613, thrift/trunk/lib/nodejs/package.json
Modified:
thrift/branches/0.6.x/ (props changed)
thrift/branches/0.6.x/compiler/cpp/src/generate/t_js_generator.cc
thrift/branches/0.6.x/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
thrift/branches/0.6.x/lib/java/test/org/apache/thrift/protocol/ProtocolTestBase.java
(props changed)
thrift/branches/0.6.x/lib/java/test/org/apache/thrift/protocol/TestTBinaryProtocol.java
(props changed)
thrift/branches/0.6.x/lib/java/test/org/apache/thrift/protocol/TestTCompactProtocol.java
(props changed)
Propchange: thrift/branches/0.6.x/
------------------------------------------------------------------------------
svn:mergeinfo = /thrift/trunk:1056442-1056613
Modified: thrift/branches/0.6.x/compiler/cpp/src/generate/t_js_generator.cc
URL:
http://svn.apache.org/viewvc/thrift/branches/0.6.x/compiler/cpp/src/generate/t_js_generator.cc?rev=1057810&r1=1057809&r2=1057810&view=diff
==============================================================================
--- thrift/branches/0.6.x/compiler/cpp/src/generate/t_js_generator.cc (original)
+++ thrift/branches/0.6.x/compiler/cpp/src/generate/t_js_generator.cc Tue Jan
11 19:21:51 2011
@@ -41,9 +41,18 @@ class t_js_generator : public t_oop_gene
const std::map<std::string, std::string>& parsed_options,
const std::string& option_string) :
t_oop_generator(program) {
- (void) parsed_options;
(void) option_string;
- out_dir_base_ = "gen-js";
+
+ std::map<std::string, std::string>::const_iterator iter;
+
+ iter = parsed_options.find("node");
+ gen_node_ = (iter != parsed_options.end());
+
+ if (gen_node_) {
+ out_dir_base_ = "gen-nodejs";
+ } else {
+ out_dir_base_ = "gen-js";
+ }
}
/**
@@ -64,6 +73,8 @@ class t_js_generator : public t_oop_gene
void generate_xception (t_struct* txception);
void generate_service (t_service* tservice);
+ std::string render_recv_throw(std::string var);
+ std::string render_recv_return(std::string var);
std::string render_const_value(t_type* type, t_const_value* value);
@@ -72,7 +83,7 @@ class t_js_generator : public t_oop_gene
* Structs!
*/
void generate_js_struct(t_struct* tstruct, bool is_exception);
- void generate_js_struct_definition(std::ofstream& out, t_struct* tstruct,
bool is_xception=false);
+ void generate_js_struct_definition(std::ofstream& out, t_struct* tstruct,
bool is_xception=false, bool is_exported=true);
void generate_js_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_js_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_js_function_helpers(t_function* tfunction);
@@ -147,7 +158,7 @@ class t_js_generator : public t_oop_gene
std::string js_includes();
std::string declare_field(t_field* tfield, bool init=false, bool obj=false);
- std::string function_signature(t_function* tfunction, std::string prefix="");
+ std::string function_signature(t_function* tfunction, std::string prefix="",
bool include_callback=false);
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
@@ -180,6 +191,20 @@ class t_js_generator : public t_oop_gene
return pieces;
}
+ std::string js_type_namespace(t_program* p) {
+ if (gen_node_) {
+ return "ttypes.";
+ }
+ return js_namespace(p);
+ }
+
+ std::string js_export_namespace(t_program* p) {
+ if (gen_node_) {
+ return "exports.";
+ }
+ return js_namespace(p);
+ }
+
std::string js_namespace(t_program* p) {
std::string ns = p->get_namespace("js");
if (ns.size() > 0) {
@@ -193,6 +218,11 @@ class t_js_generator : public t_oop_gene
private:
/**
+ * True iff we should generate NodeJS-friendly RPC services.
+ */
+ bool gen_node_;
+
+ /**
* File streams
*/
std::ofstream f_types_;
@@ -219,12 +249,16 @@ void t_js_generator::init_generator() {
// Print header
f_types_ <<
autogen_comment() <<
- js_includes();
+ js_includes() << endl;
+ if (gen_node_) {
+ f_types_ << "var ttypes = module.exports = {};" << endl;
+ }
string pns;
//setup the namespace
+ // TODO should the namespace just be in the directory structure for node?
vector<string> ns_pieces = js_namespace_pieces( program_ );
if( ns_pieces.size() > 0){
f_types_ << "var " << ns_pieces[0] << " = {}"<<endl;
@@ -244,6 +278,9 @@ void t_js_generator::init_generator() {
* Prints standard js imports
*/
string t_js_generator::js_includes() {
+ if (gen_node_) {
+ return string("var Thrift = require('thrift').Thrift;");
+ }
string inc;
return inc;
@@ -274,8 +311,7 @@ void t_js_generator::generate_typedef(t_
* @param tenum The enumeration
*/
void t_js_generator::generate_enum(t_enum* tenum) {
-
- f_types_ << js_namespace(tenum->get_program())<<tenum->get_name()<<" = {
"<<endl;
+ f_types_ << js_type_namespace(tenum->get_program())<<tenum->get_name()<<" =
{ "<<endl;
vector<t_enum_value*> constants = tenum->get_constants();
vector<t_enum_value*>::iterator c_iter;
@@ -298,7 +334,7 @@ void t_js_generator::generate_const(t_co
string name = tconst->get_name();
t_const_value* value = tconst->get_value();
- f_types_ << js_namespace(program_) << name << " = ";
+ f_types_ << js_type_namespace(program_) << name << " = ";
f_types_ << render_const_value(type, value) << endl;
}
@@ -340,7 +376,7 @@ string t_js_generator::render_const_valu
} else if (type->is_enum()) {
out << value->get_integer();
} else if (type->is_struct() || type->is_xception()) {
- out << "new " << js_namespace(type->get_program()) << type->get_name() <<
"({" << endl;
+ out << "new " << js_type_namespace(type->get_program()) <<
type->get_name() << "({" << endl;
indent_up();
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
@@ -441,16 +477,34 @@ void t_js_generator::generate_js_struct(
*/
void t_js_generator::generate_js_struct_definition(ofstream& out,
t_struct* tstruct,
- bool is_exception) {
+ bool is_exception,
+ bool is_exported) {
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
- out << js_namespace(tstruct->get_program()) << tstruct->get_name() <<" =
function(args){\n";
+ indent_up();
+ if (gen_node_) {
+ if (is_exported) {
+ out << "var " << js_namespace(tstruct->get_program()) <<
tstruct->get_name() << " = " <<
+ "module.exports." << js_namespace(tstruct->get_program()) <<
tstruct->get_name() << " = function(args){\n";
+ } else {
+ out << "var " << js_namespace(tstruct->get_program()) <<
tstruct->get_name() << " = function(args){\n";
+ }
+ } else {
+ out << js_namespace(tstruct->get_program()) << tstruct->get_name() <<" =
function(args){\n";
+ }
+
+ if (gen_node_ && is_exception) {
+ out << indent() << "Thrift.TException.call(this, \"" <<
+ js_namespace(tstruct->get_program()) << tstruct->get_name() << "\")"
<< endl;
+ out << indent() << "this.name = \"" <<
+ js_namespace(tstruct->get_program()) << tstruct->get_name() << "\""
<< endl;
+ }
//members with arguments
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- string dval = declare_field(*m_iter,true,true);
+ string dval = declare_field(*m_iter,false,true);
t_type* t = get_true_type((*m_iter)->get_type());
if ((*m_iter)->get_value() != NULL && !(t->is_struct() ||
t->is_xception())) {
dval = render_const_value((*m_iter)->get_type(),
(*m_iter)->get_value());
@@ -487,12 +541,20 @@ void t_js_generator::generate_js_struct_
out << "}\n";
if (is_exception) {
- out << "for (var property in Thrift.Exception)"<<endl<<
-
js_namespace(tstruct->get_program())<<tstruct->get_name()<<"[property] =
Thrift.Exception[property]"<<endl;
+ if (gen_node_) {
+ out << "require('util').inherits(" <<
+ js_namespace(tstruct->get_program()) <<
+ tstruct->get_name() << ", Thrift.TException)" << endl;
+ } else {
+ out << "for (var property in Thrift.TException)"<<endl<<
+
js_namespace(tstruct->get_program())<<tstruct->get_name()<<"[property] =
Thrift.TException[property]"<<endl;
+ }
}
- //init prototype
- out << js_namespace(tstruct->get_program())<<tstruct->get_name()
<<".prototype = {}\n";
+ if (!gen_node_) {
+ //init prototype
+ out << js_namespace(tstruct->get_program())<<tstruct->get_name()
<<".prototype = {}\n";
+ }
generate_js_struct_reader(out, tstruct);
@@ -632,10 +694,23 @@ void t_js_generator::generate_service(t_
string f_service_name = get_out_dir()+service_name_+".js";
f_service_.open(f_service_name.c_str());
+ f_service_ <<
+ autogen_comment() <<
+ js_includes() << endl;
+
+ if (gen_node_) {
+ f_service_ <<
+ "var ttypes = require('./" + program_->get_name() + "_types.js');" <<
endl;
+ }
+
generate_service_helpers(tservice);
generate_service_interface(tservice);
generate_service_client(tservice);
+ if (gen_node_) {
+ generate_service_processor(tservice);
+ }
+
f_service_.close();
}
@@ -645,7 +720,45 @@ void t_js_generator::generate_service(t_
* @param tservice The service to generate a server for.
*/
void t_js_generator::generate_service_processor(t_service* tservice) {
- (void) tservice;
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+
+ f_service_ <<
+ "var " << js_namespace(tservice->get_program()) << service_name_ <<
"Processor = " <<
+ "exports.Processor = function(handler) ";
+
+ scope_up(f_service_);
+
+ f_service_ << indent() << "this._handler = handler" << endl;
+
+ scope_down(f_service_);
+
+ // Generate the server implementation
+ indent(f_service_) <<
+ js_namespace(tservice->get_program()) << service_name_ <<
"Processor.prototype.process = function(input, output) ";
+
+ scope_up(f_service_);
+
+ f_service_ << indent() << "var r = input.readMessageBegin()" << endl
+ << indent() << "if (this['process_' + r.fname]) {" << endl
+ << indent() << " return this['process_' + r.fname].call(this,
r.rseqid, input, output)" << endl
+ << indent() << "} else {" << endl
+ << indent() << " input.skip(Thrift.Type.STRUCT)" << endl
+ << indent() << " input.readMessageEnd()" << endl
+ << indent() << " var x = new
Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN_METHOD,
'Unknown function ' + r.fname)" << endl
+ << indent() << " output.writeMessageBegin(r.fname,
Thrift.MessageType.Exception, r.rseqid)" << endl
+ << indent() << " x.write(output)" << endl
+ << indent() << " output.writeMessageEnd()" << endl
+ << indent() << " output.flush()" << endl
+ << indent() << "}" << endl;
+
+ scope_down(f_service_);
+ f_service_ << endl;
+
+ // Generate the process subfunctions
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+ generate_process_function(tservice, *f_iter);
+ }
}
/**
@@ -655,8 +768,70 @@ void t_js_generator::generate_service_pr
*/
void t_js_generator::generate_process_function(t_service* tservice,
t_function* tfunction) {
- (void) tservice;
- (void) tfunction;
+ indent(f_service_) <<
+ js_namespace(tservice->get_program()) << service_name_ <<
"Processor.prototype.process_" + tfunction->get_name() + " = function(seqid,
input, output) ";
+
+ scope_up(f_service_);
+
+ string argsname = js_namespace(program_)+ service_name_ + "_" +
tfunction->get_name() + "_args";
+ string resultname = js_namespace(program_)+ service_name_ + "_" +
tfunction->get_name() + "_result";
+
+ f_service_ <<
+ indent() << "var args = new " << argsname << "()" << endl <<
+ indent() << "args.read(input)" << endl <<
+ indent() << "input.readMessageEnd()" << endl;
+
+ // Declare result for non oneway function
+ if (!tfunction->is_oneway()) {
+ f_service_ <<
+ indent() << "var result = new " << resultname << "()" << endl;
+ }
+
+ // Generate the function call
+ t_struct* arg_struct = tfunction->get_arglist();
+ const std::vector<t_field*>& fields = arg_struct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ f_service_ <<
+ indent() << "this._handler." << tfunction->get_name() << "(";
+
+ bool first = true;
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+ if (first) {
+ first = false;
+ } else {
+ f_service_ << ", ";
+ }
+ f_service_ << "args." << (*f_iter)->get_name();
+ }
+
+ // Shortcut out here for oneway functions
+ if (tfunction->is_oneway()) {
+ f_service_ << ")" << endl;
+ scope_down(f_service_);
+ f_service_ << endl;
+ return;
+ }
+
+ if (!first) {
+ f_service_ << ", ";
+ }
+ f_service_ << "function(success) {" << endl;
+ indent_up();
+
+ f_service_ <<
+ indent() << "result.success = success" << endl <<
+ indent() << "output.writeMessageBegin(\"" << tfunction->get_name() <<
+ "\", Thrift.MessageType.REPLY, seqid)" << endl <<
+ indent() << "result.write(output)" << endl <<
+ indent() << "output.writeMessageEnd()" << endl <<
+ indent() << "output.flush()" << endl;
+
+ indent_down();
+ indent(f_service_) << "})" << endl;
+
+ scope_down(f_service_);
+ f_service_ << endl;
}
/**
@@ -675,7 +850,7 @@ void t_js_generator::generate_service_he
t_struct* ts = (*f_iter)->get_arglist();
string name = ts->get_name();
ts->set_name(service_name_ + "_" + name);
- generate_js_struct_definition(f_service_, ts, false);
+ generate_js_struct_definition(f_service_, ts, false, false);
generate_js_function_helpers(*f_iter);
ts->set_name(name);
}
@@ -700,7 +875,7 @@ void t_js_generator::generate_js_functio
result.append(*f_iter);
}
- generate_js_struct_definition(f_service_, &result, false);
+ generate_js_struct_definition(f_service_, &result, false, false);
}
/**
@@ -727,16 +902,31 @@ void t_js_generator::generate_service_re
void t_js_generator::generate_service_client(t_service* tservice) {
string extends = "";
- f_service_ <<
- js_namespace(tservice->get_program()) << service_name_ << "Client =
function(input, output) {"<<endl;
+ if (gen_node_) {
+ f_service_ <<
+ "var " << js_namespace(tservice->get_program()) << service_name_ <<
"Client = " <<
+ "exports.Client = function(output, pClass) {"<<endl;
+ } else {
+ f_service_ <<
+ js_namespace(tservice->get_program()) << service_name_ << "Client =
function(input, output) {"<<endl;
+ }
indent_up();
- f_service_ <<
+ if (gen_node_) {
+ f_service_ <<
+ indent() << " this.output = output;" << endl <<
+ indent() << " this.pClass = pClass;" << endl <<
+ indent() << " this.seqid = 0;" << endl <<
+ indent() << " this._reqs = {}" << endl;
+ } else {
+ f_service_ <<
indent() << " this.input = input" << endl <<
indent() << " this.output = null == output ? input : output" << endl <<
indent() << " this.seqid = 0" << endl;
+ }
+
indent_down();
@@ -766,10 +956,16 @@ void t_js_generator::generate_service_cl
string funname = (*f_iter)->get_name();
// Open function
- f_service_ <<
js_namespace(tservice->get_program())<<service_name_<<"Client.prototype." <<
function_signature(*f_iter) << "{" << endl;
+ f_service_ <<
js_namespace(tservice->get_program())<<service_name_<<"Client.prototype." <<
function_signature(*f_iter, "", gen_node_) << "{" << endl;
indent_up();
+ if (gen_node_) {
+ f_service_ <<
+ indent() << "this.seqid += 1;" << endl <<
+ indent() << "this._reqs[this.seqid] = callback;" << endl;
+ }
+
indent(f_service_) << indent() <<
"this.send_" << funname << "(";
@@ -784,7 +980,7 @@ void t_js_generator::generate_service_cl
}
f_service_ << ")" << endl;
- if (!(*f_iter)->is_oneway()) {
+ if (!gen_node_ && !(*f_iter)->is_oneway()) {
f_service_ << indent();
if (!(*f_iter)->get_returntype()->is_void()) {
f_service_ << "return ";
@@ -802,11 +998,20 @@ void t_js_generator::generate_service_cl
indent_up();
+ std::string outputVar;
+ if (gen_node_) {
+ f_service_ <<
+ indent() << "var output = new this.pClass(this.output);" << endl;
+ outputVar = "output";
+ } else {
+ outputVar = "this.output";
+ }
+
std::string argsname = js_namespace(program_)+ service_name_ + "_" +
(*f_iter)->get_name() + "_args";
// Serialize the request header
f_service_ <<
- indent() << "this.output.writeMessageBegin('" << (*f_iter)->get_name()
<< "', Thrift.MessageType.CALL, this.seqid)" << endl;
+ indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name()
<< "', Thrift.MessageType.CALL, this.seqid)" << endl;
f_service_ <<
indent() << "var args = new " << argsname << "()" << endl;
@@ -818,9 +1023,14 @@ void t_js_generator::generate_service_cl
// Write to the stream
f_service_ <<
- indent() << "args.write(this.output)" << endl <<
- indent() << "this.output.writeMessageEnd()" << endl <<
- indent() << "return this.output.getTransport().flush()" << endl;
+ indent() << "args.write(" << outputVar << ")" << endl <<
+ indent() << outputVar << ".writeMessageEnd()" << endl;
+
+ if (gen_node_) {
+ f_service_ << indent() << "return this.output.flush()" << endl;
+ } else {
+ f_service_ << indent() << "return this.output.getTransport().flush()" <<
endl;
+ }
indent_down();
@@ -830,66 +1040,88 @@ void t_js_generator::generate_service_cl
if (!(*f_iter)->is_oneway()) {
std::string resultname = js_namespace(tservice->get_program()) +
service_name_ + "_" + (*f_iter)->get_name() + "_result";
- t_struct noargs(program_);
- t_function recv_function((*f_iter)->get_returntype(),
- string("recv_") + (*f_iter)->get_name(),
- &noargs);
- // Open function
- f_service_ <<
- endl << js_namespace(tservice->get_program())<<service_name_ <<
- "Client.prototype." << function_signature(&recv_function) << "{" <<
endl;
+ if (gen_node_) {
+ // Open function
+ f_service_ <<
+ endl << js_namespace(tservice->get_program())<<service_name_ <<
+ "Client.prototype.recv_" << (*f_iter)->get_name() << " =
function(input,mtype,rseqid){" << endl;
+ } else {
+ t_struct noargs(program_);
+
+ t_function recv_function((*f_iter)->get_returntype(),
+ string("recv_") + (*f_iter)->get_name(),
+ &noargs);
+ // Open function
+ f_service_ <<
+ endl << js_namespace(tservice->get_program())<<service_name_ <<
+ "Client.prototype." << function_signature(&recv_function) << "{"
<< endl;
+ }
indent_up();
- f_service_ <<
+ std::string inputVar;
+ if (gen_node_) {
+ inputVar = "input";
+ } else {
+ inputVar = "this.input";
+ }
+
+ if (gen_node_) {
+ f_service_ <<
+ indent() << "var callback = this._reqs[rseqid] || function() {};" <<
endl <<
+ indent() << "delete this._reqs[rseqid];" << endl;
+ } else {
+ f_service_ <<
indent() << "var ret = this.input.readMessageBegin()" << endl <<
indent() << "var fname = ret.fname" << endl <<
indent() << "var mtype = ret.mtype" << endl <<
- indent() << "var rseqid= ret.rseqid" <<endl <<
+ indent() << "var rseqid= ret.rseqid" <<endl;
+ }
+
+ f_service_ <<
indent() << "if (mtype == Thrift.MessageType.EXCEPTION) {" << endl <<
- indent() << " var x = new Thrift.ApplicationException()" << endl <<
- indent() << " x.read(this.input)" << endl <<
- indent() << " this.input.readMessageEnd()" << endl <<
- indent() << " throw x" << endl <<
+ indent() << " var x = new Thrift.TApplicationException()" << endl <<
+ indent() << " x.read(" << inputVar << ")" << endl <<
+ indent() << " " << inputVar << ".readMessageEnd()" << endl <<
+ indent() << " " << render_recv_throw("x") << endl <<
indent() << "}" << endl;
f_service_ <<
indent() << "var result = new " << resultname << "()" << endl <<
- indent() << "result.read(this.input)" << endl;
+ indent() << "result.read(" << inputVar << ")" << endl;
f_service_ <<
- indent() << "this.input.readMessageEnd()" << endl <<
+ indent() << inputVar << ".readMessageEnd()" << endl <<
endl;
- // Careful, only return result if not a void function
- if (!(*f_iter)->get_returntype()->is_void()) {
- f_service_ <<
- indent() << "if (null != result.success ) {" << endl <<
- indent() << " return result.success" << endl <<
- indent() << "}" << endl;
- }
-
t_struct* xs = (*f_iter)->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
f_service_ <<
indent() << "if (null != result." << (*x_iter)->get_name() << ") {"
<< endl <<
- indent() << " throw result." << (*x_iter)->get_name() << endl <<
+ indent() << " " << render_recv_throw("result." +
(*x_iter)->get_name()) << endl <<
indent() << "}" << endl;
}
- // Careful, only return _result if not a void function
- if ((*f_iter)->get_returntype()->is_void()) {
- indent(f_service_) <<
- "return" << endl;
- } else {
+ // Careful, only return result if not a void function
+ if (!(*f_iter)->get_returntype()->is_void()) {
f_service_ <<
- indent() << "throw \"" << (*f_iter)->get_name() << " failed: unknown
result\"" << endl;
+ indent() << "if (null != result.success ) {" << endl <<
+ indent() << " " << render_recv_return("result.success") << endl <<
+ indent() << "}" << endl;
+ f_service_ <<
+ indent() << render_recv_throw("\"" + (*f_iter)->get_name() + "
failed: unknown result\"") << endl;
+ } else {
+ if (gen_node_) {
+ indent(f_service_) << "callback(null)" << endl;
+ } else {
+ indent(f_service_) << "return" << endl;
+ }
}
// Close function
@@ -901,6 +1133,22 @@ void t_js_generator::generate_service_cl
}
+std::string t_js_generator::render_recv_throw(std::string var) {
+ if (gen_node_) {
+ return "return callback(" + var + ");";
+ } else {
+ return "throw " + var;
+ }
+}
+
+std::string t_js_generator::render_recv_return(std::string var) {
+ if (gen_node_) {
+ return "return callback(null, " + var + ");";
+ } else {
+ return "return " + var;
+ }
+}
+
/**
* Deserializes a field of any type.
*/
@@ -925,7 +1173,7 @@ void t_js_generator::generate_deserializ
} else if (type->is_container()) {
generate_deserialize_container(out, type, name);
} else if (type->is_base_type() || type->is_enum()) {
- indent(out) << "var rtmp = input.";
+ indent(out) << name << " = input.";
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
@@ -961,11 +1209,12 @@ void t_js_generator::generate_deserializ
} else if (type->is_enum()) {
out << "readI32()";
}
- out << endl;
-
- out <<name << " = rtmp.value"<<endl;
+ if (!gen_node_) {
+ out << ".value";
+ }
+ out << endl;
} else {
printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
tfield->get_name().c_str(), type->get_name().c_str());
@@ -982,7 +1231,7 @@ void t_js_generator::generate_deserializ
t_struct* tstruct,
string prefix) {
out <<
- indent() << prefix << " = new " <<
js_namespace(tstruct->get_program())<<tstruct->get_name() << "()" << endl <<
+ indent() << prefix << " = new " <<
js_type_namespace(tstruct->get_program())<<tstruct->get_name() << "()" << endl
<<
indent() << prefix << ".read(input)" << endl;
}
@@ -1082,9 +1331,9 @@ void t_js_generator::generate_deserializ
t_field fval(tmap->get_val_type(), val);
indent(out) <<
- declare_field(&fkey, true, false) << endl;
+ declare_field(&fkey, false, false) << endl;
indent(out) <<
- declare_field(&fval, true, false) << endl;
+ declare_field(&fval, false, false) << endl;
generate_deserialize_field(out, &fkey);
generate_deserialize_field(out, &fval);
@@ -1252,9 +1501,12 @@ void t_js_generator::generate_serialize_
string viter = tmp("viter");
indent(out) << "for(var "<<kiter<<" in "<<prefix<<")";
scope_up(out);
+ indent(out) << "if ("<<prefix<<".hasOwnProperty("<<kiter<<"))" <<endl;
+ scope_up(out);
indent(out) << "var "<<viter<<" = "<<prefix<<"["<<kiter<<"]"<<endl;
generate_serialize_map_element(out, (t_map*)ttype, kiter, viter);
scope_down(out);
+ scope_down(out);
} else if (ttype->is_set()) {
@@ -1262,9 +1514,12 @@ void t_js_generator::generate_serialize_
indent(out) <<
"for(var "<<iter<<" in " << prefix << ")" << endl;
scope_up(out);
+ indent(out) << "if ("<<prefix<<".hasOwnProperty("<<iter<<"))" <<endl;
+ scope_up(out);
indent(out) << iter << "=" << prefix << "[" << iter << "]"<< endl;
generate_serialize_set_element(out, (t_set*)ttype, iter);
scope_down(out);
+ scope_down(out);
} else if (ttype->is_list()) {
@@ -1272,9 +1527,12 @@ void t_js_generator::generate_serialize_
indent(out) <<
"for(var "<<iter<<" in "<< prefix << ")" << endl;
scope_up(out);
+ indent(out) << "if ("<<prefix<<".hasOwnProperty("<<iter<<"))" <<endl;
+ scope_up(out);
indent(out) << iter << "=" << prefix << "[" << iter << "]"<< endl;
generate_serialize_list_element(out, (t_list*)ttype, iter);
scope_down(out);
+ scope_down(out);
}
scope_down(out);
@@ -1367,11 +1625,13 @@ string t_js_generator::declare_field(t_f
result += " = null";
} else if (type->is_struct() || type->is_xception()) {
if (obj) {
- result += " = new " +js_namespace(type->get_program()) +
type->get_name() + "()";
+ result += " = new " +js_type_namespace(type->get_program()) +
type->get_name() + "()";
} else {
result += " = null";
}
}
+ } else {
+ result += " = null";
}
return result;
}
@@ -1383,7 +1643,8 @@ string t_js_generator::declare_field(t_f
* @return String of rendered function definition
*/
string t_js_generator::function_signature(t_function* tfunction,
- string prefix) {
+ string prefix,
+ bool include_callback) {
string str;
@@ -1402,6 +1663,12 @@ string t_js_generator::function_signatur
str += (*f_iter)->get_name();
}
+ if (include_callback) {
+ if (!fields.empty()) {
+ str += ",";
+ }
+ str += "callback";
+ }
str += ")";
return str;
@@ -1469,5 +1736,6 @@ string t_js_generator ::type_to_enum(t_t
}
-THRIFT_REGISTER_GENERATOR(js, "Javascript", "")
+THRIFT_REGISTER_GENERATOR(js, "Javascript",
+" node: Generate node.js compatible code.\n")
Modified:
thrift/branches/0.6.x/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
URL:
http://svn.apache.org/viewvc/thrift/branches/0.6.x/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs?rev=1057810&r1=1057809&r2=1057810&view=diff
==============================================================================
---
thrift/branches/0.6.x/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
(original)
+++
thrift/branches/0.6.x/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
Tue Jan 11 19:21:51 2011
@@ -56,5 +56,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision
Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.6.0.*")]
+[assembly: AssemblyVersion("0.7.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Propchange:
thrift/branches/0.6.x/lib/java/test/org/apache/thrift/protocol/ProtocolTestBase.java
('svn:mergeinfo' removed)
Propchange:
thrift/branches/0.6.x/lib/java/test/org/apache/thrift/protocol/TestTBinaryProtocol.java
('svn:mergeinfo' removed)
Propchange:
thrift/branches/0.6.x/lib/java/test/org/apache/thrift/protocol/TestTCompactProtocol.java
('svn:mergeinfo' removed)