From 60d79c7343555c8c97ea8c5dce4d00dd0b09191f Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Fri, 18 Jul 2014 21:46:21 -0400 Subject: [PATCH 01/34] Initial work on combyne templates --- generate/filters/cpp_to_v8.js | 5 + generate/filters/default_value.js | 3 + generate/filters/is_pointer.js | 3 + generate/filters/is_v8_value.js | 14 +++ generate/filters/un_pointer.js | 3 + generate/index.js | 75 +++++++----- .../asyncFunction.cc.ejs | 0 generate/partials/async_function.cc | 0 .../convertFromV8.cc.ejs | 0 .../convertToV8.cc.ejs | 0 generate/partials/convert_from_v8.cc | 0 generate/partials/convert_to_v8.cc | 0 generate/partials/doc.cc | 27 +++++ generate/{templates => partials}/doc.cc.ejs | 0 generate/partials/fields.cc | 0 .../{templates => partials}/fields.cc.ejs | 0 .../guardArguments.cc.ejs | 0 generate/partials/guard_arguments.cc | 0 .../syncFunction.cc.ejs | 0 generate/partials/sync_function.cc | 0 .../{binding.gyp.ejs => binding.gyp} | 8 +- generate/templates/class.cc | 111 ++++++++++++++++++ generate/templates/header.h | 110 +++++++++++++++++ .../templates/{nodegit.cc.ejs => nodegit.cc} | 16 ++- generate/util/file.js | 24 ++++ package.json | 1 + 26 files changed, 356 insertions(+), 44 deletions(-) create mode 100644 generate/filters/cpp_to_v8.js create mode 100644 generate/filters/default_value.js create mode 100644 generate/filters/is_pointer.js create mode 100644 generate/filters/is_v8_value.js create mode 100644 generate/filters/un_pointer.js rename generate/{templates => partials}/asyncFunction.cc.ejs (100%) create mode 100644 generate/partials/async_function.cc rename generate/{templates => partials}/convertFromV8.cc.ejs (100%) rename generate/{templates => partials}/convertToV8.cc.ejs (100%) create mode 100644 generate/partials/convert_from_v8.cc create mode 100644 generate/partials/convert_to_v8.cc create mode 100644 generate/partials/doc.cc rename generate/{templates => partials}/doc.cc.ejs (100%) create mode 100644 generate/partials/fields.cc rename generate/{templates => partials}/fields.cc.ejs (100%) rename generate/{templates => partials}/guardArguments.cc.ejs (100%) create mode 100644 generate/partials/guard_arguments.cc rename generate/{templates => partials}/syncFunction.cc.ejs (100%) create mode 100644 generate/partials/sync_function.cc rename generate/templates/{binding.gyp.ejs => binding.gyp} (89%) create mode 100644 generate/templates/class.cc create mode 100644 generate/templates/header.h rename generate/templates/{nodegit.cc.ejs => nodegit.cc} (59%) create mode 100644 generate/util/file.js diff --git a/generate/filters/cpp_to_v8.js b/generate/filters/cpp_to_v8.js new file mode 100644 index 000000000..dcf017a4f --- /dev/null +++ b/generate/filters/cpp_to_v8.js @@ -0,0 +1,5 @@ +var isV8Value = require("./is_v8_value"); + +module.exports = function(cppClassName) { + return isV8Value(cppClassName) ? cppClassName : "Object"; +}; diff --git a/generate/filters/default_value.js b/generate/filters/default_value.js new file mode 100644 index 000000000..42682549e --- /dev/null +++ b/generate/filters/default_value.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return cType === "git_otype" ? "GIT_OBJ_ANY" : "0"; +}; diff --git a/generate/filters/is_pointer.js b/generate/filters/is_pointer.js new file mode 100644 index 000000000..edfe4afc6 --- /dev/null +++ b/generate/filters/is_pointer.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return /\s*\*\s*$/.test(cType); +}; diff --git a/generate/filters/is_v8_value.js b/generate/filters/is_v8_value.js new file mode 100644 index 000000000..f773ff6a2 --- /dev/null +++ b/generate/filters/is_v8_value.js @@ -0,0 +1,14 @@ +var v8 = [ + "Boolean", + "Number", + "String", + "Integer", + "Int32", + "Uint32", + "Date", + "Function" +]; + +module.exports = function(cppClassName) { + return v8.indexOf(cppClassName) > -1; +}; diff --git a/generate/filters/un_pointer.js b/generate/filters/un_pointer.js new file mode 100644 index 000000000..99382f36f --- /dev/null +++ b/generate/filters/un_pointer.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return cType.replace(/\s*\*\s*$/, ""); +}; diff --git a/generate/index.js b/generate/index.js index 977078bda..320686805 100644 --- a/generate/index.js +++ b/generate/index.js @@ -1,44 +1,57 @@ -// https://github.com/nodegit/nodegit/issues/94 -const fs = require("fs"); -const ejs = require("ejs"); const path = require("path"); +const combyne = require("combyne"); +const file = require("./util/file"); const idefs = require("./idefs"); -var local = path.join.bind(null, __dirname); - -var classTemplate = ejs.compile( - "" + fs.readFileSync(local("templates/class.cc.ejs")), { - filename: "class.cc" - }); - -var headerTemplate = ejs.compile( - "" + fs.readFileSync(local("templates/header.h.ejs")), { - filename: "header.h" - }); - -var bindingTemplate = ejs.compile( - "" + fs.readFileSync(local("templates/binding.gyp.ejs")), {}); +// Customize the delimiters so as to not process `{{{` or `}}}`. +combyne.settings.delimiters = { + START_RAW: "{{=", + END_RAW: "=}}" +}; + +var partial = { + asyncFunction: file.read("partials/async_function.cc"), + convertFromV8: file.read("partials/convert_from_v8.cc"), + convertToV8: file.read("partials/convert_to_v8.cc"), + doc: file.read("partials/doc.cc"), + fields: file.read("partials/fields.cc"), + guardArguments: file.read("partials/guard_arguments.cc"), + syncFunction: file.read("partials/sync_function.cc") +}; + +var template = { + class: file.read("templates/class.cc"), + //fs.readFileSync(local("templates/header.h")), + //fs.readFileSync(local("templates/binding.gyp")), + binding: file.read("templates/binding.gyp"), + nodegit: file.read("templates/nodegit.cc") +}; + +// Convert Buffers to Combyne templates. +Object.keys(template).forEach(function(name) { + template[name] = combyne(template[name]); +}); -var nodegitSourceTemplate = ejs.compile( - "" + fs.readFileSync(local("templates/nodegit.cc.ejs")), {}); +// Attach all partials to select templates. +Object.keys(partial).forEach(function(name) { + template.class.registerPartial(name, combyne(partial[name])); +}); +// Determine which definitions to actually include in the source code. var enabled = idefs.filter(function(idef) { + // Additionally provide a friendly name to the actual filename. idef.name = path.basename(idef.filename, ".h"); + return !idef.ignore; }); -enabled.forEach(function(idef) { - fs.writeFileSync(local("../include/", idef.filename), headerTemplate(idef)); - - fs.writeFileSync( - local("../src/", path.basename(idef.filename, ".h")) + ".cc", - classTemplate(idef)); +// TODO Wipe out all existing source files. - fs.writeFileSync(local("../binding.gyp"), bindingTemplate({ - idefs: idefs - })); +// Write out single purpose templates. +file.write("../binding.gyp", template.binding.render(enabled)); +file.write("../src/nodegit.cc", template.nodegit.render(enabled)); - fs.writeFileSync(local("../src/nodegit.cc"), nodegitSourceTemplate({ - idefs: idefs - })); +// Write out all the classes. +enabled.forEach(function(idef) { + file.write("../src/" + idef.name + ".cc", template.class.render(idef)); }); diff --git a/generate/templates/asyncFunction.cc.ejs b/generate/partials/asyncFunction.cc.ejs similarity index 100% rename from generate/templates/asyncFunction.cc.ejs rename to generate/partials/asyncFunction.cc.ejs diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc new file mode 100644 index 000000000..e69de29bb diff --git a/generate/templates/convertFromV8.cc.ejs b/generate/partials/convertFromV8.cc.ejs similarity index 100% rename from generate/templates/convertFromV8.cc.ejs rename to generate/partials/convertFromV8.cc.ejs diff --git a/generate/templates/convertToV8.cc.ejs b/generate/partials/convertToV8.cc.ejs similarity index 100% rename from generate/templates/convertToV8.cc.ejs rename to generate/partials/convertToV8.cc.ejs diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc new file mode 100644 index 000000000..e69de29bb diff --git a/generate/partials/convert_to_v8.cc b/generate/partials/convert_to_v8.cc new file mode 100644 index 000000000..e69de29bb diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc new file mode 100644 index 000000000..10be2b8e2 --- /dev/null +++ b/generate/partials/doc.cc @@ -0,0 +1,27 @@ +<% + for (var i = 0; i < functionInfo.args.length; i++) { + var arg = functionInfo.args[i]; + if (arg.isReturn || arg.isSelf) continue; +-%> +<% } -%> + +<% for (var r = 0; r < returns.length; r++) { -%> +<% if (functionInfo.isAsync) { -%> +<% } else { -%> +<% } -%> +<% } -%> + +{%each functionInfo.args%} + {%if not arg.isReturn and not arg.isSelf%} + * @param {{{ jsClassName }}} {{ name }} + {%endif%} + +{%endeach%} + +{%each returns%} + {%if functionInfo.isAsync%} + * @param {{{ jsClassName }}} callback + {%else%} + * @return {{{ jsClassName }}} {%if name%}{{ name }}{%else%}{{'result'}}{%endeach%} + {%endif%} +{%endeach%} diff --git a/generate/templates/doc.cc.ejs b/generate/partials/doc.cc.ejs similarity index 100% rename from generate/templates/doc.cc.ejs rename to generate/partials/doc.cc.ejs diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc new file mode 100644 index 000000000..e69de29bb diff --git a/generate/templates/fields.cc.ejs b/generate/partials/fields.cc.ejs similarity index 100% rename from generate/templates/fields.cc.ejs rename to generate/partials/fields.cc.ejs diff --git a/generate/templates/guardArguments.cc.ejs b/generate/partials/guardArguments.cc.ejs similarity index 100% rename from generate/templates/guardArguments.cc.ejs rename to generate/partials/guardArguments.cc.ejs diff --git a/generate/partials/guard_arguments.cc b/generate/partials/guard_arguments.cc new file mode 100644 index 000000000..e69de29bb diff --git a/generate/templates/syncFunction.cc.ejs b/generate/partials/syncFunction.cc.ejs similarity index 100% rename from generate/templates/syncFunction.cc.ejs rename to generate/partials/syncFunction.cc.ejs diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc new file mode 100644 index 000000000..e69de29bb diff --git a/generate/templates/binding.gyp.ejs b/generate/templates/binding.gyp similarity index 89% rename from generate/templates/binding.gyp.ejs rename to generate/templates/binding.gyp index b5dd98cba..588d66054 100644 --- a/generate/templates/binding.gyp.ejs +++ b/generate/templates/binding.gyp @@ -12,10 +12,10 @@ "src/nodegit.cc", "src/wrapper.cc", "src/functions/copy.cc", - <% idefs.forEach(function(idef) { -%> - "src/<%- idef.name %>.cc", - <% }); -%> - ], + {%each%} + "src/{{ name }}.cc", + {%endeach%} + ], "include_dirs": [ "vendor/libv8-convert", diff --git a/generate/templates/class.cc b/generate/templates/class.cc new file mode 100644 index 000000000..1913f5d50 --- /dev/null +++ b/generate/templates/class.cc @@ -0,0 +1,111 @@ +// This is a generated file, modify: generate/templates/class.cc.ejs. +#include +#include + +extern "C" { +#include +} + +#include "../include/functions/copy.h" +#include "../include/{{ filename }}" + +{%each dependencies as dependency%} +#include "{{ dependency }}" +{%endeach%} + +using namespace v8; +using namespace node; + +{%if cType%} +{{ cppClassName }}::{{ cppClassName }}({{ cType }} *raw) { + this->raw = raw; +} + +{{ cppClassName }}::~{{ cppClassName }}() { + {%if freeFunctionName%}{{ freeFunctionName }}(this->raw);{%endif%} +} + +void {{ cppClassName }}::Initialize(Handle target) { + NanScope(); + + Local tpl = NanNew(New); + + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(NanNew("{{ jsClassName }}")); + + {%each functions as function%} + {%if not function.ignore%} + {%if function.isPrototypeMethod%} + NODE_SET_PROTOTYPE_METHOD(tpl, "{{ function.jsFunctionName }}", {{ function.cppFunctionName }}); + {%else%} + NODE_SET_METHOD(tpl, "{{ function.jsFunctionName }}", {{ function.cppFunctionName }}); + {%endif%} + {%endif%} + {%endeach%} + + {%each fields as field%} + {%if not field.ignore%} + NODE_SET_PROTOTYPE_METHOD(tpl, "{{ field.jsFunctionName }}", {{ field.cppFunctionName }}); + {%endif%} + {%endeach%} + + Local _constructor_template = tpl->GetFunction(); + NanAssignPersistent(constructor_template, _constructor_template); + target->Set(NanNew("{{ jsClassName }}"), _constructor_template); +} + +NAN_METHOD({{ cppClassName }}::New) { + NanScope(); + + if (args.Length() == 0 || !args[0]->IsExternal()) { + return NanThrowError("{{ cType }} is required."); + } + {{ cppClassName }}* object = new {{ cppClassName }}(static_cast<{{ cType }} *>(Handle::Cast(args[0])->Value())); + object->Wrap(args.This()); + + NanReturnValue(args.This()); +} + +Handle {{ cppClassName }}::New(void *raw) { + NanEscapableScope(); + Handle argv[1] = { NanNew((void *)raw) }; + return NanEscapeScope(NanNew({{ cppClassName }}::constructor_template)->NewInstance(1, argv)); +} + +{{ cType }} *{{ cppClassName }}::GetValue() { + return this->raw; +} +{%else%} +void {{ cppClassName }}::Initialize(Handle target) { + NanScope(); + + Local object = NanNew(); + + {%each functions as function%} + {%if not function.ignore%} + NODE_SET_METHOD(object, "{{ function.jsFunctionName }}", {{ function.cppFunctionName }}); + {%endif%} + {%endeach%} + + target->Set(NanNew("{{ jsClassName }}"), object); +} +{%endif%} + +{%each functions as function%} + {%if not function.ignore%} + {%each function.args as arg%} + {%endeach%} + {%endif%} + + {%if function.isAsync%} + {%partial asyncFunction .%} + {%else%} + {%partial syncFunction .%} + {%endif%} +{%endeach%} + +{%partial fields .%} + +{%if cType%} +Persistent {{ cppClassName }}::constructor_template; +{%endif%} diff --git a/generate/templates/header.h b/generate/templates/header.h new file mode 100644 index 000000000..a338ac5c4 --- /dev/null +++ b/generate/templates/header.h @@ -0,0 +1,110 @@ +#ifndef {{ cppClassName.toUpperCase() }}_H +#define {{ cppClassName.toUpperCase() }}_H + +#include +#include + +extern "C" { +#include +} + +//{%each dependencies as dependency%} +#include "<%- dependencies[d] %>" +//{%endeach%} + +<% if (typeof forwardDeclare !== "undefined") { %> +// Forward declaration. +struct <%- cType %> { + <% if (typeof fields != 'undefined') { %> + <% + for (var i in fields) { + var fieldInfo = fields[i]; + if (fieldInfo.ignore || !fieldInfo.cppFunctionName) continue; + -%> + + <%- fieldInfo.structType || fieldInfo.cType -%> <%- fieldInfo.structName || fieldInfo.name %>; + <% } -%> + <% } -%> + +}; +<% } -%> + +using namespace node; +using namespace v8; + +class <%- cppClassName %> : public ObjectWrap { + public: + + static Persistent constructor_template; + static void Initialize (Handle target); + +<% if (cType != undefined) { -%> + <%- cType %> *GetValue(); + + static Handle New(void *raw); +<% } -%> + + private: +<% if (cType != undefined) { -%> + <%- cppClassName %>(<%- cType %> *raw); + ~<%- cppClassName %>(); +<% } -%> + + static NAN_METHOD(New); + +<% if (typeof fields != 'undefined') { -%> +<% + for (var i in fields) { + var fieldInfo = fields[i]; + if (fieldInfo.ignore || !fieldInfo.cppFunctionName) continue; +-%> + static NAN_METHOD(<%- fieldInfo.cppFunctionName %>); +<% } -%> +<% } -%> +<% if (typeof functions != 'undefined') { -%> +<% + for (var i in functions) { + var functionInfo = functions[i]; + if (functionInfo.ignore || !functionInfo.cppFunctionName) continue; +-%> +<% if (functionInfo.isAsync) { -%> + + struct <%- functionInfo.cppFunctionName %>Baton { + int error_code; + const git_error* error; +<% + for (var i = 0; i < functionInfo.args.length; i++) { + var arg = functionInfo.args[i]; +-%> +<% if (arg.isReturn) { -%> + <%- arg.cType.replace('**', '*') %> <%- arg.name %>; +<% } else { -%> + <%- arg.cType %> <%- arg.name %>; +<% } -%> +<% } -%> + }; + class <%- functionInfo.cppFunctionName %>Worker : public NanAsyncWorker { + public: + <%- functionInfo.cppFunctionName %>Worker( + <%- functionInfo.cppFunctionName %>Baton *_baton, + NanCallback *callback + ) : NanAsyncWorker(callback) + , baton(_baton) {}; + ~<%- functionInfo.cppFunctionName %>Worker() {}; + void Execute(); + void HandleOKCallback(); + + private: + <%- functionInfo.cppFunctionName %>Baton *baton; + }; +<% } -%> + static NAN_METHOD(<%- functionInfo.cppFunctionName %>); +<% } -%> +<% } -%> +<% if (cType != undefined) { -%> + <%- cType %> *raw; +<% } -%> +}; + +#endif + diff --git a/generate/templates/nodegit.cc.ejs b/generate/templates/nodegit.cc similarity index 59% rename from generate/templates/nodegit.cc.ejs rename to generate/templates/nodegit.cc index 3036ff7b8..5a1deefd7 100644 --- a/generate/templates/nodegit.cc.ejs +++ b/generate/templates/nodegit.cc @@ -1,24 +1,22 @@ // This is a generated file, modify: generate/templates/nodegit.cc.ejs. #include #include - -#include "git2.h" +#include #include "../include/wrapper.h" #include "../include/functions/copy.h" - -<% idefs.forEach(function(idef) { -%> -#include "../include/<%- idef.filename %>" -<% }); -%> +{%each%} +#include "../include/{{ filename }}" +{%endeach%} extern "C" void init(Handle target) { NanScope(); Wrapper::Initialize(target); -<% idefs.forEach(function(idef) { -%> - <%- idef.cppClassName %>::Initialize(target); -<% }); -%> + {%each%} + {{ cppClassName }}::Initialize(target); + {%endeach%} } NODE_MODULE(nodegit, init) diff --git a/generate/util/file.js b/generate/util/file.js new file mode 100644 index 000000000..c595a7687 --- /dev/null +++ b/generate/util/file.js @@ -0,0 +1,24 @@ +const fs = require("fs"); +const path = require("path"); + +// Make a locally bound path joiner. +var local = path.join.bind(null, __dirname, "../"); + +exports.read = function(file) { + try { + return fs.readFileSync(local(file)).toString(); + } + catch (unhandledException) { + return ""; + } +}; + +exports.write = function(file, contents) { + try { + fs.writeFileSync(local(file), contents); + return true; + } + catch (unhandledException) { + return false; + } +}; diff --git a/package.json b/package.json index 0fa56e90e..6a8dd9dd3 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "node-pre-gyp": "~0.5.16", "q": "~1.0.1", "ejs": "~1.0.0", + "combyne": "~5.0.0", "request": "~2.36.0", "rimraf": "~2.2.8", "tar": "~0.1.19", From 391b3edbdaee3efb0ed88cc3230dd5aab10ab656 Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Tue, 22 Jul 2014 14:16:12 -0400 Subject: [PATCH 02/34] Started working on replacing the header template This is the initial work for porting over the header template to use Combyne instead of EJS. It adds in a few helpers that are necessary to replace missing features that EJS provides like JS boolean logic. --- generate/filters/or.js | 3 + generate/filters/replace.js | 3 + generate/filters/upper.js | 3 + generate/index.js | 39 +++++++---- generate/partials/fields.cc | 16 +++++ generate/templates/header.h | 117 ++++++++++++++------------------ generate/templates/header.h.ejs | 112 ------------------------------ 7 files changed, 101 insertions(+), 192 deletions(-) create mode 100644 generate/filters/or.js create mode 100644 generate/filters/replace.js create mode 100644 generate/filters/upper.js delete mode 100644 generate/templates/header.h.ejs diff --git a/generate/filters/or.js b/generate/filters/or.js new file mode 100644 index 000000000..fe02c2a87 --- /dev/null +++ b/generate/filters/or.js @@ -0,0 +1,3 @@ +module.exports = function(value, other) { + return value || other; +}; diff --git a/generate/filters/replace.js b/generate/filters/replace.js new file mode 100644 index 000000000..15ed9c71f --- /dev/null +++ b/generate/filters/replace.js @@ -0,0 +1,3 @@ +module.exports = function(value, find, replace) { + return value.replace(find, replace); +}; diff --git a/generate/filters/upper.js b/generate/filters/upper.js new file mode 100644 index 000000000..bf0aa534b --- /dev/null +++ b/generate/filters/upper.js @@ -0,0 +1,3 @@ +module.exports = function(value) { + return value.toUpperCase(); +}; diff --git a/generate/index.js b/generate/index.js index 320686805..5c50b86b7 100644 --- a/generate/index.js +++ b/generate/index.js @@ -9,7 +9,7 @@ combyne.settings.delimiters = { END_RAW: "=}}" }; -var partial = { +var partials = { asyncFunction: file.read("partials/async_function.cc"), convertFromV8: file.read("partials/convert_from_v8.cc"), convertToV8: file.read("partials/convert_to_v8.cc"), @@ -19,39 +19,50 @@ var partial = { syncFunction: file.read("partials/sync_function.cc") }; -var template = { - class: file.read("templates/class.cc"), - //fs.readFileSync(local("templates/header.h")), - //fs.readFileSync(local("templates/binding.gyp")), +var templates = { +// class: file.read("templates/class.cc"), + header: file.read("templates/header.h"), binding: file.read("templates/binding.gyp"), nodegit: file.read("templates/nodegit.cc") }; +var filters = { + upper: require("./filters/upper"), + replace: require("./filters/replace"), + or: require("./filters/or") +}; + // Convert Buffers to Combyne templates. -Object.keys(template).forEach(function(name) { - template[name] = combyne(template[name]); +Object.keys(templates).forEach(function(template) { + templates[template] = combyne(templates[template]); + + // Attach all filters to all templates. + Object.keys(filters).forEach(function(filter) { + templates[template].registerFilter(filter, filters[filter]); + }); }); // Attach all partials to select templates. -Object.keys(partial).forEach(function(name) { - template.class.registerPartial(name, combyne(partial[name])); -}); +//Object.keys(partials).forEach(function(partial) { +// templates.class.registerPartial(partial, combyne(partials[partial])); +//}); + // Determine which definitions to actually include in the source code. var enabled = idefs.filter(function(idef) { // Additionally provide a friendly name to the actual filename. idef.name = path.basename(idef.filename, ".h"); - return !idef.ignore; }); // TODO Wipe out all existing source files. // Write out single purpose templates. -file.write("../binding.gyp", template.binding.render(enabled)); -file.write("../src/nodegit.cc", template.nodegit.render(enabled)); +file.write("../binding.gyp", templates.binding.render(enabled)); +file.write("../src/nodegit.cc", templates.nodegit.render(enabled)); // Write out all the classes. enabled.forEach(function(idef) { - file.write("../src/" + idef.name + ".cc", template.class.render(idef)); + //file.write("../src/" + idef.name + ".cc", templates.class.render(idef)); + file.write("../include/" + idef.name + ".h", templates.header.render(idef)); }); diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc index e69de29bb..c4a632446 100644 --- a/generate/partials/fields.cc +++ b/generate/partials/fields.cc @@ -0,0 +1,16 @@ +{%each fields as field%} + {%if not field.ignore%} + +NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { + NanScope(); + <% var to = fieldInfo; -%> + Handle to; + + <%- fieldInfo.cType %> <% if (!isV8Value(fieldInfo.cppClassName)) { %>*<% } %><%- fieldInfo.name %> = + <% if (!isV8Value(fieldInfo.cppClassName)) { %>&<% } %>ObjectWrap::Unwrap<<%- cppClassName %>>(args.This())->GetValue()-><%- fieldInfo.name %>; + + <% include convertToV8.cc.ejs -%> + NanReturnValue(to); +} +<% } -%> +<% } -%> diff --git a/generate/templates/header.h b/generate/templates/header.h index a338ac5c4..51772b31f 100644 --- a/generate/templates/header.h +++ b/generate/templates/header.h @@ -8,103 +8,88 @@ extern "C" { #include } -//{%each dependencies as dependency%} -#include "<%- dependencies[d] %>" -//{%endeach%} +{%each dependencies as dependency%} +#include "{{ dependency }}" +{%endeach%} -<% if (typeof forwardDeclare !== "undefined") { %> +{%if forwardDeclare%} // Forward declaration. -struct <%- cType %> { - <% if (typeof fields != 'undefined') { %> - <% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore || !fieldInfo.cppFunctionName) continue; - -%> - - <%- fieldInfo.structType || fieldInfo.cType -%> <%- fieldInfo.structName || fieldInfo.name %>; - <% } -%> - <% } -%> - +struct {{ cType }} { + {%each fields as field%} + {%if not field.ignore%} + {{ field.structType|or field.cType }} {{ field.structName|or field.name }}; + {%endif%} + {%endeach%} }; -<% } -%> +{%endif%} using namespace node; using namespace v8; -class <%- cppClassName %> : public ObjectWrap { +class {{ cppClassName }} : public ObjectWrap { public: static Persistent constructor_template; static void Initialize (Handle target); -<% if (cType != undefined) { -%> - <%- cType %> *GetValue(); + {%if cType%} + {{ cType }} *GetValue(); static Handle New(void *raw); -<% } -%> + {%endif%} private: -<% if (cType != undefined) { -%> - <%- cppClassName %>(<%- cType %> *raw); - ~<%- cppClassName %>(); -<% } -%> + {%if cType%} + {{ cppClassName }}({{ cType }} *raw); + ~{{ cppClassName }}(); + {%endif%} static NAN_METHOD(New); -<% if (typeof fields != 'undefined') { -%> -<% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore || !fieldInfo.cppFunctionName) continue; --%> - static NAN_METHOD(<%- fieldInfo.cppFunctionName %>); -<% } -%> -<% } -%> -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore || !functionInfo.cppFunctionName) continue; --%> -<% if (functionInfo.isAsync) { -%> - - struct <%- functionInfo.cppFunctionName %>Baton { + {%each fields as field%} + {%if not field.ignore%} + static NAN_METHOD({{ field.cppFunctionName }}); + {%endif%} + {%endeach%} + + {%each functions as function%} + {%if not function.ignore%} + {%if function.isAsync%} + + struct {{ function.cppFunctionName }}Baton { int error_code; const git_error* error; -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; --%> -<% if (arg.isReturn) { -%> - <%- arg.cType.replace('**', '*') %> <%- arg.name %>; -<% } else { -%> - <%- arg.cType %> <%- arg.name %>; -<% } -%> -<% } -%> + {%each function.args as arg%} + {%if arg.isReturn%} + {{ arg.cType|replace "**" "*" }} {{ arg.name }}; + {%else%} + {{ arg.cType }} {{ arg.name }}; + {%endif%} + {%endeach%} }; - class <%- functionInfo.cppFunctionName %>Worker : public NanAsyncWorker { + class {{ function.cppFunctionName }}Worker : public NanAsyncWorker { public: - <%- functionInfo.cppFunctionName %>Worker( - <%- functionInfo.cppFunctionName %>Baton *_baton, + {{ function.cppFunctionName }}Worker( + {{ function.cppFunctionName }}Baton *_baton, NanCallback *callback ) : NanAsyncWorker(callback) , baton(_baton) {}; - ~<%- functionInfo.cppFunctionName %>Worker() {}; + ~{{ function.cppFunctionName }}Worker() {}; void Execute(); void HandleOKCallback(); private: - <%- functionInfo.cppFunctionName %>Baton *baton; + {{ function.cppFunctionName }}Baton *baton; }; -<% } -%> - static NAN_METHOD(<%- functionInfo.cppFunctionName %>); -<% } -%> -<% } -%> -<% if (cType != undefined) { -%> - <%- cType %> *raw; -<% } -%> + {%endif%} + + static NAN_METHOD({{ function.cppFunctionName }}); + {%endif%} + {%endeach%} + + {%if cType%} + {{ cType }} *raw; + {%endif%} }; #endif - diff --git a/generate/templates/header.h.ejs b/generate/templates/header.h.ejs deleted file mode 100644 index 8280ab1ff..000000000 --- a/generate/templates/header.h.ejs +++ /dev/null @@ -1,112 +0,0 @@ -// This is a generated file, modify: generate/templates/header.h.ejs. -#ifndef <%- cppClassName.toUpperCase() %>_H -#define <%- cppClassName.toUpperCase() %>_H - -#include -#include - -extern "C" { -#include -} - -<% if (typeof dependencies != 'undefined') { -%> -<% for (d in dependencies) { -%> -#include "<%- dependencies[d] %>" -<% } -%> -<% } -%> - -<% if (typeof forwardDeclare !== "undefined") { %> -// Forward declaration. -struct <%- cType %> { - <% if (typeof fields != 'undefined') { %> - <% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore || !fieldInfo.cppFunctionName) continue; - -%> - - <%- fieldInfo.structType || fieldInfo.cType -%> <%- fieldInfo.structName || fieldInfo.name %>; - <% } -%> - <% } -%> - -}; -<% } -%> - -using namespace node; -using namespace v8; - -class <%- cppClassName %> : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - -<% if (cType != undefined) { -%> - <%- cType %> *GetValue(); - - static Handle New(void *raw); -<% } -%> - - private: -<% if (cType != undefined) { -%> - <%- cppClassName %>(<%- cType %> *raw); - ~<%- cppClassName %>(); -<% } -%> - - static NAN_METHOD(New); - -<% if (typeof fields != 'undefined') { -%> -<% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore || !fieldInfo.cppFunctionName) continue; --%> - static NAN_METHOD(<%- fieldInfo.cppFunctionName %>); -<% } -%> -<% } -%> -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore || !functionInfo.cppFunctionName) continue; --%> -<% if (functionInfo.isAsync) { -%> - - struct <%- functionInfo.cppFunctionName %>Baton { - int error_code; - const git_error* error; -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; --%> -<% if (arg.isReturn) { -%> - <%- arg.cType.replace('**', '*') %> <%- arg.name %>; -<% } else { -%> - <%- arg.cType %> <%- arg.name %>; -<% } -%> -<% } -%> - }; - class <%- functionInfo.cppFunctionName %>Worker : public NanAsyncWorker { - public: - <%- functionInfo.cppFunctionName %>Worker( - <%- functionInfo.cppFunctionName %>Baton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~<%- functionInfo.cppFunctionName %>Worker() {}; - void Execute(); - void HandleOKCallback(); - - private: - <%- functionInfo.cppFunctionName %>Baton *baton; - }; -<% } -%> - static NAN_METHOD(<%- functionInfo.cppFunctionName %>); -<% } -%> -<% } -%> -<% if (cType != undefined) { -%> - <%- cType %> *raw; -<% } -%> -}; - -#endif From f522bd67dfec7060e8f624a73299526efa18406e Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 24 Sep 2014 19:16:55 -0400 Subject: [PATCH 03/34] Upgraded all dependencies --- package.json | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 6a8dd9dd3..f650656a5 100644 --- a/package.json +++ b/package.json @@ -40,27 +40,27 @@ "node-pre-gyp" ], "dependencies": { - "fs-extra": "~0.9.1", - "nan": "~1.2.0", - "node-gyp": "~0.13.1", - "node-pre-gyp": "~0.5.16", - "q": "~1.0.1", - "ejs": "~1.0.0", - "combyne": "~5.0.0", - "request": "~2.36.0", - "rimraf": "~2.2.8", - "tar": "~0.1.19", - "which": "~1.0.5", - "promise": "~4.0.0", - "promisify-node": "~0.1.2" + "fs-extra": "^0.12.0", + "nan": "^1.3.0", + "node-gyp": "^1.0.2", + "node-pre-gyp": "^0.5.27", + "q": "^1.0.1", + "ejs": "^1.0.0", + "combyne": "^0.5.2", + "request": "^2.44.0", + "rimraf": "^2.2.8", + "tar": "^1.0.1", + "which": "^1.0.5", + "promise": "^6.0.0", + "promisify-node": "^0.1.2" }, "devDependencies": { - "async": "~0.9.0", - "aws-sdk": "~2.0.0-rc.20", - "istanbul": "~0.2.14", - "jshint": "~2.5.1", - "mocha": "~1.20.1", - "nodeunit": "~0.9.0" + "async": "^0.9.0", + "aws-sdk": "^2.0.17", + "istanbul": "^0.3.2", + "jshint": "^2.5.6", + "mocha": "^1.21.4", + "nodeunit": "^0.9.0" }, "binary": { "module_name": "nodegit", From 5953faad20796cd33904d053563b72fa8135d17b Mon Sep 17 00:00:00 2001 From: John Haley Date: Thu, 25 Sep 2014 10:42:28 -0700 Subject: [PATCH 04/34] Converting more templates to Combyne --- generate/filters/and.js | 3 + generate/filters/args_info.js | 32 +++++++ generate/filters/convert_returns.js | 19 ++++ generate/filters/has_return_type.js | 7 ++ generate/filters/js_args_count.js | 14 +++ generate/filters/returns.js | 18 ++++ generate/index.js | 18 ++-- generate/partials/async_function.cc | 134 +++++++++++++++++++++++++++ generate/partials/convert_from_v8.cc | 32 +++++++ generate/partials/doc.cc | 23 +---- generate/partials/guard_arguments.cc | 9 ++ generate/templates/class.cc | 15 ++- generate/types.json | 3 +- 13 files changed, 293 insertions(+), 34 deletions(-) create mode 100644 generate/filters/and.js create mode 100644 generate/filters/args_info.js create mode 100644 generate/filters/convert_returns.js create mode 100644 generate/filters/has_return_type.js create mode 100644 generate/filters/js_args_count.js create mode 100644 generate/filters/returns.js diff --git a/generate/filters/and.js b/generate/filters/and.js new file mode 100644 index 000000000..042631623 --- /dev/null +++ b/generate/filters/and.js @@ -0,0 +1,3 @@ +module.exports = function(value, other) { + return value && other; +}; diff --git a/generate/filters/args_info.js b/generate/filters/args_info.js new file mode 100644 index 000000000..544f2ee11 --- /dev/null +++ b/generate/filters/args_info.js @@ -0,0 +1,32 @@ +var cppToV8 = require("./cpp_to_v8"); + +module.exports = function(args) { + var result = [], + cArg, + jsArg; + + for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { + var arg = args[cArg]; + + if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { + arg.isJsArg = true; + arg.jsArg = jsArg; + + jsArg++; + } + + if (cArg >= args.length -1) { + arg.lastArg = true; + } + else { + arg.lastArg = false; + } + + arg.cArg = cArg; + arg.v8ValueClassName = cppToV8(arg.cppClassName); + + result.push(arg); + } + + return result; +}; diff --git a/generate/filters/convert_returns.js b/generate/filters/convert_returns.js new file mode 100644 index 000000000..3bc190a4a --- /dev/null +++ b/generate/filters/convert_returns.js @@ -0,0 +1,19 @@ +module.exports = function(returns) { + var result = []; + + if (returns.length == 1) { + var singleReturn = {}; + + singleReturn.__proto__ = returns[0]; + singleReturn.name = "baton->" + to.name; + + result.push(singleReturn); + } + else { + returns.forEach(function (_return) { + result.push(_return); + }); + } + + return result; +}; diff --git a/generate/filters/has_return_type.js b/generate/filters/has_return_type.js new file mode 100644 index 000000000..2d21a0e66 --- /dev/null +++ b/generate/filters/has_return_type.js @@ -0,0 +1,7 @@ +module.exports = function(functionInfo) { + if (functionInfo.return) { + return functionInfo.return.cType != "void" || functionInfo.return.isErrorCode; + } + + return false; +}; diff --git a/generate/filters/js_args_count.js b/generate/filters/js_args_count.js new file mode 100644 index 000000000..85bc3e76d --- /dev/null +++ b/generate/filters/js_args_count.js @@ -0,0 +1,14 @@ +module.exports = function(args) { + var cArg, + jsArg; + + for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { + var arg = args[cArg]; + + if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { + jsArg++; + } + } + + return jsArg; +}; diff --git a/generate/filters/returns.js b/generate/filters/returns.js new file mode 100644 index 000000000..5e7505799 --- /dev/null +++ b/generate/filters/returns.js @@ -0,0 +1,18 @@ +module.exports = function(functionInfo) { + var result = []; + + (functionInfo.args || []).forEach(function(arg) { + if (arg.isReturn) { + result.push(arg); + } + }); + + if (!result.length + && functionInfo.return + && !functionInfo.return.isErrorCode + && functionInfo.return.cType != "void"){ + result.push(functionInfo.return); + } + + return result; +}; diff --git a/generate/index.js b/generate/index.js index 5c50b86b7..965880700 100644 --- a/generate/index.js +++ b/generate/index.js @@ -20,7 +20,7 @@ var partials = { }; var templates = { -// class: file.read("templates/class.cc"), + class: file.read("templates/class.cc"), header: file.read("templates/header.h"), binding: file.read("templates/binding.gyp"), nodegit: file.read("templates/nodegit.cc") @@ -29,7 +29,13 @@ var templates = { var filters = { upper: require("./filters/upper"), replace: require("./filters/replace"), - or: require("./filters/or") + or: require("./filters/or"), + returns: require("./filters/returns"), + argsInfo: require("./filters/args_info"), + jsArgsCount: require("./filters/js_args_count"), + isV8Value: require("./filters/is_v8_value"), + hasReturnType: require("./filters/has_return_type"), + convertReturns: require("./filters/convert_returns") }; // Convert Buffers to Combyne templates. @@ -43,9 +49,9 @@ Object.keys(templates).forEach(function(template) { }); // Attach all partials to select templates. -//Object.keys(partials).forEach(function(partial) { -// templates.class.registerPartial(partial, combyne(partials[partial])); -//}); +Object.keys(partials).forEach(function(partial) { + templates.class.registerPartial(partial, combyne(partials[partial])); +}); // Determine which definitions to actually include in the source code. @@ -63,6 +69,6 @@ file.write("../src/nodegit.cc", templates.nodegit.render(enabled)); // Write out all the classes. enabled.forEach(function(idef) { - //file.write("../src/" + idef.name + ".cc", templates.class.render(idef)); + file.write("../src/" + idef.name + ".cc", templates.class.render(idef)); file.write("../include/" + idef.name + ".h", templates.header.render(idef)); }); diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index e69de29bb..06cfded19 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -0,0 +1,134 @@ +/** +{%partial doc .%} + */ +NAN_METHOD({{ cppClassName }}::{{ functionInfo.cppFunctionName }}) { + NanScope(); + {%partial guard_arguments .%} + + if (args.Length() == {{functionInfo.args|jsArgsCount}} || !args[{{functionInfo.args|jsArgsCount}}]->IsFunction()) { + return NanThrowError("Callback is required and must be a Function."); + } + + {{ functionInfo.cppFunctionName }}Baton* baton = new {{ functionInfo.cppFunctionName }}Baton; + baton->error_code = GIT_OK; + baton->error = NULL; + {%each functionInfo.args|argsInfo as arg %} + {%if not arg.isReturn %} + {%if arg.isSelf %} + baton->{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue(); + {%elsif arg.name $} + {%partial convert_from_v8 .%} + {%if not arg.isPayload %} + baton->{{ arg.name }} = from_{{ arg.name }}; + {%endif} + {%endif%} + {%elsif arg.shouldAlloc %} + baton->{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|replace '*' '') }})); + {%endif%} + {%endeach%} + + NanCallback *callback = new NanCallback(Local::Cast(args[{{functionInfo.args|jsArgsCount}}])); + {{ functionInfo.cppFunctionName }}Worker *worker = new {{ functionInfo.cppFunctionName }}Worker(baton, callback); + {%each functionInfo.args|argsInfo as arg %} + {%if not arg.isReturn %} + {%if arg.isSelf %} + worker->SaveToPersistent("{{ arg.name }}", args.This()); + {%else%} + if (!args[{{ arg.jsArg }}]->IsUndefined() && !args[{{ arg.jsArg }}]->IsNull()) + { + worker->SaveToPersistent("{{ arg.name }}", args[{{ arg.jsArg }}]->ToObject()); + } + {%endif%} + {%endif%} + {%endeach%} + + NanAsyncQueueWorker(worker); + NanReturnUndefined(); +} + +void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::Execute() { + {%if functionInfo|hasReturnType %} + {{ functionInfo.return.cType }} result = + {%endif%} + {{ functionInfo.cFunctionName }}( + {%-- Insert Function Arguments --%} + {%each functionInfo.args|argsInfo as arg %} + {%-- turn the pointer into a ref %} + {%if arg.isReturn|and arg.cType|isPointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} + {%endeach%} + ); + + {%if functionInfo.return.isErrorCode %} + baton->error_code = result; + + if (result != GIT_OK && giterr_last() != NULL) { + baton->error = git_error_dup(giterr_last()); + } + + {%elsif not functionInfo.return.cType == 'void' %} + + baton->result = result; + + {%endif%} +} + +void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::HandleOKCallback() { + TryCatch try_catch; + if (baton->error_code == GIT_OK) { + {%if not returns.length %} + Handle result = NanUndefined(); + {%else%} + {%each returns|converReturns as return %} + {%if returns.length == 1 %} + Handle to; + {%partial convertToV8 return %} + Handle result = to; + {%else%} + Handle result = NanNew(); + Handle to; + {%partial convertToV8 return %} + result->Set(NanNew("{{ result.jsName | or result.name }}"), to); + {%endif%} + {%endeach%} + {%endif%} + Handle argv[2] = { + NanNull(), + result + }; + callback->Call(2, argv); + } else { + if (baton->error) { + Handle argv[1] = { + NanError(baton->error->message) + }; + callback->Call(1, argv); + if (baton->error->message) + free((void *)baton->error->message); + free((void *)baton->error); + } else { + callback->Call(0, NULL); + } + + {%each functionInfo.args as arg %} + {%if arg.shouldAlloc %} + free(baton-><%= arg.name %>); + {%endif%} + {%endeach%} + } + + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + + {%each functionInfo.args as arg %} + {%if arg.cppClassName == 'String' | or arg.cppClassName == 'Array' %} + {%if arg.freeFunctionName %} + {{ arg.freeFunctionName }}(baton->{{ arg.name }}); + {%else%} + free((void *)baton->{{ arg.name }}); + {%endif%} + {%endif%} + {%endeach%} + + delete baton; +} diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc index e69de29bb..08826932d 100644 --- a/generate/partials/convert_from_v8.cc +++ b/generate/partials/convert_from_v8.cc @@ -0,0 +1,32 @@ +{%if not arg.isPayload %} + {{ arg.cType }} from_{{ arg.name }}; + {%if arg.isOptional %} + if (args{{[ arg.jsArg }}]->Is{{ arg.v8ValueClassName }}()) { + {%endif%} + {%if arg.cppClassName == 'String' %} + String::Utf8Value {{ arg.name }}(args[{{ arg.jsArg }}]->ToString()); + from_{{ arg.name }} = ({{ arg.cType }}) strdup(*{{ arg.name }}); + {%elsif arg.cppClassName == 'Array' %} + Array *tmp_{{ arg.name }} = Array::Cast(*args[{{ arg.jsArg }}]); + from_{{ arg.name }} = ({{ arg.cType }})malloc(tmp_{{ arg.name }}->Length() * sizeof({{ arg.cType|replace '**' '*' }})); + for (unsigned int i = 0; i < tmp_{{ arg.name }}->Length(); i++) { + {%-- + // FIXME: should recursively call convertFromv8. + --%} + from_{{ arg.name }}[i] = ObjectWrap::Unwrap<{{ arg.arrayElementCppClassName }}>(tmp_{{ arg.name }}->Get(NanNew(static_cast(i)))->ToObject())->GetValue(); + } + {%elsif arg.cppClassName == 'Function' %} + {%elsif arg.cppClassName == 'Buffer' %} + from_{{ arg.name }} = Buffer::Data(args[{{ arg.jsArg }}]->ToObject()); + {%elsif arg.cppClassName|isV8Value %} + from_{{ arg.name }} = ({{ arg.cType }}) {{ arg.additionalCast }} {{ arg.cast }} args[{{ arg.jsArg }}]->To{{ arg.cppClassName }}()->Value(); + {%else%} + from_{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args[{{ arg.jsArg }}]->ToObject())->GetValue(); + {%endif%} + + {%if arg.isOptional %} + } else { + from_{{ arg.name }} = 0; + } + {%endif%}} +{%endif%} diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index 10be2b8e2..31b77beaf 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -1,27 +1,14 @@ -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (arg.isReturn || arg.isSelf) continue; --%> -<% } -%> - -<% for (var r = 0; r < returns.length; r++) { -%> -<% if (functionInfo.isAsync) { -%> -<% } else { -%> -<% } -%> -<% } -%> - -{%each functionInfo.args%} +{%each functionInfo.args as arg%} {%if not arg.isReturn and not arg.isSelf%} - * @param {{{ jsClassName }}} {{ name }} + * @param {{ arg.jsClassName }} {{ arg.name }} {%endif%} {%endeach%} -{%each returns%} +{%each functionInfo|returns as returnInfo%} {%if functionInfo.isAsync%} - * @param {{{ jsClassName }}} callback + * @param {{ returnInfo.jsClassName }} callback {%else%} - * @return {{{ jsClassName }}} {%if name%}{{ name }}{%else%}{{'result'}}{%endeach%} + * @return {{ returnInfo.jsClassName }} {%if returnInfo.name%}{{ returnInfo.name }}{%else%}{{'result'}}{%endeach%} {%endif%} {%endeach%} diff --git a/generate/partials/guard_arguments.cc b/generate/partials/guard_arguments.cc index e69de29bb..728186aeb 100644 --- a/generate/partials/guard_arguments.cc +++ b/generate/partials/guard_arguments.cc @@ -0,0 +1,9 @@ +{%each functionInfo.args|argsInfo as arg%} + {%if arg.isJsArg%} + {%if not arg.isOptional%} + if (args.Length() == {{arg.jsArg}} || !args[{{jsArg}}]->Is{{arg.v8ValueClassName}}()) { + return NanThrowError("{{arg.jsClassName}} {{arg.name}} is required."); + } + {%endif%} + {%endif%} +{%endeach%} diff --git a/generate/templates/class.cc b/generate/templates/class.cc index 1913f5d50..f6ad1aedf 100644 --- a/generate/templates/class.cc +++ b/generate/templates/class.cc @@ -1,4 +1,4 @@ -// This is a generated file, modify: generate/templates/class.cc.ejs. +// This is a generated file, modify: generate/templates/class.cc. #include #include @@ -93,14 +93,11 @@ void {{ cppClassName }}::Initialize(Handle target) { {%each functions as function%} {%if not function.ignore%} - {%each function.args as arg%} - {%endeach%} - {%endif%} - - {%if function.isAsync%} - {%partial asyncFunction .%} - {%else%} - {%partial syncFunction .%} + {%if function.isAsync%} + {%partial asyncFunction .%} + {%else%} + {%partial syncFunction .%} + {%endif%} {%endif%} {%endeach%} diff --git a/generate/types.json b/generate/types.json index a664a78d4..9199f6e24 100644 --- a/generate/types.json +++ b/generate/types.json @@ -3365,6 +3365,7 @@ "js": "Config" }, "const git_config **": { + "cpp": "GitConfig", "js": "Config" }, "git_config_find_global *": { @@ -9147,4 +9148,4 @@ "cpp": "InitInitOptions", "js": "initInitOptions" } -} +} \ No newline at end of file From 6a92dd24dfcc332d5bfa2adfd68ba2e2a91c2604 Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 26 Sep 2014 10:56:19 -0700 Subject: [PATCH 05/34] Missed an els tag --- generate/partials/async_function.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 06cfded19..66196893f 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -111,7 +111,7 @@ void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::HandleOKCallb {%each functionInfo.args as arg %} {%if arg.shouldAlloc %} - free(baton-><%= arg.name %>); + free(baton->{{ arg.name }}); {%endif%} {%endeach%} } @@ -129,6 +129,6 @@ void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::HandleOKCallb {%endif%} {%endif%} {%endeach%} - + delete baton; } From 6cffb84832de4c68bd6770aef4c8f4c966eb9671 Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 26 Sep 2014 11:00:46 -0700 Subject: [PATCH 06/34] Starting to fix template compile time errors --- generate/partials/async_function.cc | 4 ++-- generate/partials/doc.cc | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 66196893f..a89dbedff 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -17,13 +17,13 @@ NAN_METHOD({{ cppClassName }}::{{ functionInfo.cppFunctionName }}) { {%if arg.isSelf %} baton->{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue(); {%elsif arg.name $} - {%partial convert_from_v8 .%} + {%partial convertFromV8 .%} {%if not arg.isPayload %} baton->{{ arg.name }} = from_{{ arg.name }}; {%endif} {%endif%} {%elsif arg.shouldAlloc %} - baton->{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|replace '*' '') }})); + baton->{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|replace '*' '' }})); {%endif%} {%endeach%} diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index 31b77beaf..ae74442c1 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -2,13 +2,12 @@ {%if not arg.isReturn and not arg.isSelf%} * @param {{ arg.jsClassName }} {{ arg.name }} {%endif%} - {%endeach%} {%each functionInfo|returns as returnInfo%} {%if functionInfo.isAsync%} * @param {{ returnInfo.jsClassName }} callback {%else%} - * @return {{ returnInfo.jsClassName }} {%if returnInfo.name%}{{ returnInfo.name }}{%else%}{{'result'}}{%endeach%} + * @return {{ returnInfo.jsClassName }} {%if returnInfo.name%}{{ returnInfo.name }}{%else%}result{%endeach%} {%endif%} {%endeach%} From ed07f2a6f7735e04acbb1455dbe06acce8ca7c82 Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 26 Sep 2014 11:09:03 -0700 Subject: [PATCH 07/34] Fixed more compile time errors --- generate/index.js | 1 + generate/partials/doc.cc | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/generate/index.js b/generate/index.js index 965880700..b94e2378c 100644 --- a/generate/index.js +++ b/generate/index.js @@ -30,6 +30,7 @@ var filters = { upper: require("./filters/upper"), replace: require("./filters/replace"), or: require("./filters/or"), + and: require("./filters/and"), returns: require("./filters/returns"), argsInfo: require("./filters/args_info"), jsArgsCount: require("./filters/js_args_count"), diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index ae74442c1..bb8a8fe66 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -1,13 +1,15 @@ -{%each functionInfo.args as arg%} - {%if not arg.isReturn and not arg.isSelf%} +{%each functionInfo.args as arg %} + {%if not arg.isReturn %} + {%if not arg.isSelf %} * @param {{ arg.jsClassName }} {{ arg.name }} + {%endif%} {%endif%} {%endeach%} -{%each functionInfo|returns as returnInfo%} - {%if functionInfo.isAsync%} +{%each functionInfo|returns as returnInfo %} + {%if functionInfo.isAsync %} * @param {{ returnInfo.jsClassName }} callback {%else%} - * @return {{ returnInfo.jsClassName }} {%if returnInfo.name%}{{ returnInfo.name }}{%else%}result{%endeach%} + * @return {{ returnInfo.jsClassName }} {%if returnInfo.name %}{{ returnInfo.name }}{%else%}result{%endif%} {%endif%} {%endeach%} From 82167de01a2480ec73c76292a352bf25dc8f08a6 Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 26 Sep 2014 13:20:45 -0700 Subject: [PATCH 08/34] Stopped using a reserved word in the template. --- generate/partials/async_function.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index a89dbedff..ed15e7731 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -78,16 +78,16 @@ void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::HandleOKCallb {%if not returns.length %} Handle result = NanUndefined(); {%else%} - {%each returns|converReturns as return %} + {%each returns|converReturns as _return %} {%if returns.length == 1 %} Handle to; - {%partial convertToV8 return %} + {%partial convertToV8 _return %} Handle result = to; {%else%} Handle result = NanNew(); Handle to; - {%partial convertToV8 return %} - result->Set(NanNew("{{ result.jsName | or result.name }}"), to); + {%partial convertToV8 _return %} + result->Set(NanNew("{{ _return.jsName | or _return.name }}"), to); {%endif%} {%endeach%} {%endif%} From 16f9358d3ac5f0610d67ce5c228b1246c025507b Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 26 Sep 2014 16:58:29 -0400 Subject: [PATCH 09/34] Bump Combyne version to fix partials issue --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f650656a5..e8a9673d7 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "node-pre-gyp": "^0.5.27", "q": "^1.0.1", "ejs": "^1.0.0", - "combyne": "^0.5.2", + "combyne": "^0.5.5", "request": "^2.44.0", "rimraf": "^2.2.8", "tar": "^1.0.1", From 38d7fc7a4ec9c9d5e1ca145a1e08ba85e8f37808 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 26 Sep 2014 17:10:23 -0400 Subject: [PATCH 10/34] Remove functionInfo references --- generate/partials/async_function.cc | 34 ++++++++++++++-------------- generate/partials/doc.cc | 8 ++++--- generate/partials/guard_arguments.cc | 2 +- generate/templates/class.cc | 4 ++-- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index ed15e7731..6fabfb1bf 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -1,18 +1,18 @@ /** {%partial doc .%} */ -NAN_METHOD({{ cppClassName }}::{{ functionInfo.cppFunctionName }}) { +NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { NanScope(); - {%partial guard_arguments .%} + {%partial guardArguments .%} - if (args.Length() == {{functionInfo.args|jsArgsCount}} || !args[{{functionInfo.args|jsArgsCount}}]->IsFunction()) { + if (args.Length() == {{args|jsArgsCount}} || !args[{{args|jsArgsCount}}]->IsFunction()) { return NanThrowError("Callback is required and must be a Function."); } - {{ functionInfo.cppFunctionName }}Baton* baton = new {{ functionInfo.cppFunctionName }}Baton; + {{ cppFunctionName }}Baton* baton = new {{ cppFunctionName }}Baton; baton->error_code = GIT_OK; baton->error = NULL; - {%each functionInfo.args|argsInfo as arg %} + {%each args|argsInfo as arg %} {%if not arg.isReturn %} {%if arg.isSelf %} baton->{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue(); @@ -27,9 +27,9 @@ NAN_METHOD({{ cppClassName }}::{{ functionInfo.cppFunctionName }}) { {%endif%} {%endeach%} - NanCallback *callback = new NanCallback(Local::Cast(args[{{functionInfo.args|jsArgsCount}}])); - {{ functionInfo.cppFunctionName }}Worker *worker = new {{ functionInfo.cppFunctionName }}Worker(baton, callback); - {%each functionInfo.args|argsInfo as arg %} + NanCallback *callback = new NanCallback(Local::Cast(args[{{args|jsArgsCount}}])); + {{ cppFunctionName }}Worker *worker = new {{ cppFunctionName }}Worker(baton, callback); + {%each args|argsInfo as arg %} {%if not arg.isReturn %} {%if arg.isSelf %} worker->SaveToPersistent("{{ arg.name }}", args.This()); @@ -46,33 +46,33 @@ NAN_METHOD({{ cppClassName }}::{{ functionInfo.cppFunctionName }}) { NanReturnUndefined(); } -void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::Execute() { +void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { {%if functionInfo|hasReturnType %} - {{ functionInfo.return.cType }} result = + {{ return.cType }} result = {%endif%} - {{ functionInfo.cFunctionName }}( + {{ cFunctionName }}( {%-- Insert Function Arguments --%} - {%each functionInfo.args|argsInfo as arg %} + {%each args|argsInfo as arg %} {%-- turn the pointer into a ref %} {%if arg.isReturn|and arg.cType|isPointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} {%endeach%} ); - {%if functionInfo.return.isErrorCode %} + {%if return.isErrorCode %} baton->error_code = result; if (result != GIT_OK && giterr_last() != NULL) { baton->error = git_error_dup(giterr_last()); } - {%elsif not functionInfo.return.cType == 'void' %} + {%elsif not return.cType == 'void' %} baton->result = result; {%endif%} } -void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::HandleOKCallback() { +void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { TryCatch try_catch; if (baton->error_code == GIT_OK) { {%if not returns.length %} @@ -109,7 +109,7 @@ void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::HandleOKCallb callback->Call(0, NULL); } - {%each functionInfo.args as arg %} + {%each args as arg %} {%if arg.shouldAlloc %} free(baton->{{ arg.name }}); {%endif%} @@ -120,7 +120,7 @@ void {{ cppClassName }}::{{ functionInfo.cppFunctionName }}Worker::HandleOKCallb node::FatalException(try_catch); } - {%each functionInfo.args as arg %} + {%each args as arg %} {%if arg.cppClassName == 'String' | or arg.cppClassName == 'Array' %} {%if arg.freeFunctionName %} {{ arg.freeFunctionName }}(baton->{{ arg.name }}); diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index bb8a8fe66..f6e398986 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -1,4 +1,4 @@ -{%each functionInfo.args as arg %} +{%each args as arg %} {%if not arg.isReturn %} {%if not arg.isSelf %} * @param {{ arg.jsClassName }} {{ arg.name }} @@ -6,10 +6,12 @@ {%endif%} {%endeach%} -{%each functionInfo|returns as returnInfo %} - {%if functionInfo.isAsync %} +{%-- +{%each .|returns as returnInfo %} + {%if isAsync %} * @param {{ returnInfo.jsClassName }} callback {%else%} * @return {{ returnInfo.jsClassName }} {%if returnInfo.name %}{{ returnInfo.name }}{%else%}result{%endif%} {%endif%} {%endeach%} +--%} diff --git a/generate/partials/guard_arguments.cc b/generate/partials/guard_arguments.cc index 728186aeb..2cddb87d1 100644 --- a/generate/partials/guard_arguments.cc +++ b/generate/partials/guard_arguments.cc @@ -1,4 +1,4 @@ -{%each functionInfo.args|argsInfo as arg%} +{%each args|argsInfo as arg%} {%if arg.isJsArg%} {%if not arg.isOptional%} if (args.Length() == {{arg.jsArg}} || !args[{{jsArg}}]->Is{{arg.v8ValueClassName}}()) { diff --git a/generate/templates/class.cc b/generate/templates/class.cc index f6ad1aedf..f65cf9c3c 100644 --- a/generate/templates/class.cc +++ b/generate/templates/class.cc @@ -94,9 +94,9 @@ void {{ cppClassName }}::Initialize(Handle target) { {%each functions as function%} {%if not function.ignore%} {%if function.isAsync%} - {%partial asyncFunction .%} + {%partial asyncFunction function%} {%else%} - {%partial syncFunction .%} + {%partial syncFunction function%} {%endif%} {%endif%} {%endeach%} From b7b5c119fa5d85b59cab98d59d03b96d915149e8 Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 26 Sep 2014 13:57:53 -0700 Subject: [PATCH 11/34] Updated gitignore to include log files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 099191756..621086ef2 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ /include/* !/include/functions/copy.h !/include/wrapper.h + +*.log From 8d440d97c335b886e827504aa606eff0bf6a8223 Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 26 Sep 2014 16:50:00 -0700 Subject: [PATCH 12/34] Added more combyne template files --- generate/filters/convert_returns.js | 7 ++++- generate/filters/fields_info.js | 11 ++++++++ generate/filters/is_double_pointer.js | 3 ++ generate/filters/is_pointer.js | 2 +- generate/index.js | 5 +++- generate/partials/async_function.cc | 6 ++-- generate/partials/convert_from_v8.cc | 40 +++++++++++++-------------- generate/partials/convert_to_v8.cc | 39 ++++++++++++++++++++++++++ generate/partials/fields.cc | 15 +++++----- 9 files changed, 94 insertions(+), 34 deletions(-) create mode 100644 generate/filters/fields_info.js create mode 100644 generate/filters/is_double_pointer.js diff --git a/generate/filters/convert_returns.js b/generate/filters/convert_returns.js index 3bc190a4a..6dab7fbf9 100644 --- a/generate/filters/convert_returns.js +++ b/generate/filters/convert_returns.js @@ -5,12 +5,17 @@ module.exports = function(returns) { var singleReturn = {}; singleReturn.__proto__ = returns[0]; - singleReturn.name = "baton->" + to.name; + singleReturn.parsedName = "baton->" + to.name; + singleReturn.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(singleReturn.cppClassName); + singleReturn.parsedClassName = (singleReturn.cppClassName || '').toLowerCase() + "_t"; result.push(singleReturn); } else { returns.forEach(function (_return) { + _return.parsedName = _return.name; + _return.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(_return.cppClassName); + _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; result.push(_return); }); } diff --git a/generate/filters/fields_info.js b/generate/filters/fields_info.js new file mode 100644 index 000000000..64109e732 --- /dev/null +++ b/generate/filters/fields_info.js @@ -0,0 +1,11 @@ +module.exports = function(fields) { + var result = []; + + fields.forEach(function (field){ + field.parsedName = field.name || "result"; + field.isCppClassIntType = ~["Uin32", "Int32"].indexOf(field.cppClassName); + field.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; + }); + + return result; +}; diff --git a/generate/filters/is_double_pointer.js b/generate/filters/is_double_pointer.js new file mode 100644 index 000000000..9d1246ab4 --- /dev/null +++ b/generate/filters/is_double_pointer.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return /\s*\*\*\s*/.test(cType); +}; diff --git a/generate/filters/is_pointer.js b/generate/filters/is_pointer.js index edfe4afc6..a5dbb053e 100644 --- a/generate/filters/is_pointer.js +++ b/generate/filters/is_pointer.js @@ -1,3 +1,3 @@ module.exports = function(cType) { - return /\s*\*\s*$/.test(cType); + return /\s*\*\s*/.test(cType); }; diff --git a/generate/index.js b/generate/index.js index b94e2378c..4533931b2 100644 --- a/generate/index.js +++ b/generate/index.js @@ -35,8 +35,11 @@ var filters = { argsInfo: require("./filters/args_info"), jsArgsCount: require("./filters/js_args_count"), isV8Value: require("./filters/is_v8_value"), + isPointer: require("./filters/is_pointer"), + isDoublePointer: require("./filters/is_double_pointer"), hasReturnType: require("./filters/has_return_type"), - convertReturns: require("./filters/convert_returns") + convertReturns: require("./filters/convert_returns"), + fieldsInfo: require("./filters/fields_info") }; // Convert Buffers to Combyne templates. diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 6fabfb1bf..efb22177d 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -17,7 +17,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%if arg.isSelf %} baton->{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue(); {%elsif arg.name $} - {%partial convertFromV8 .%} + {%partial convertFromV8 arg%} {%if not arg.isPayload %} baton->{{ arg.name }} = from_{{ arg.name }}; {%endif} @@ -54,7 +54,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { {%-- Insert Function Arguments --%} {%each args|argsInfo as arg %} {%-- turn the pointer into a ref %} - {%if arg.isReturn|and arg.cType|isPointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} + {%if arg.isReturn|and arg.cType|isDoublePointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} {%endeach%} ); @@ -78,7 +78,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { {%if not returns.length %} Handle result = NanUndefined(); {%else%} - {%each returns|converReturns as _return %} + {%each returns|convertReturns as _return %} {%if returns.length == 1 %} Handle to; {%partial convertToV8 _return %} diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc index 08826932d..e0b845495 100644 --- a/generate/partials/convert_from_v8.cc +++ b/generate/partials/convert_from_v8.cc @@ -1,32 +1,32 @@ -{%if not arg.isPayload %} - {{ arg.cType }} from_{{ arg.name }}; - {%if arg.isOptional %} - if (args{{[ arg.jsArg }}]->Is{{ arg.v8ValueClassName }}()) { +{%if not isPayload %} + {{ cType }} from_{{ name }}; + {%if isOptional %} + if (args{{[ jsArg }}]->Is{{ v8ValueClassName }}()) { {%endif%} - {%if arg.cppClassName == 'String' %} - String::Utf8Value {{ arg.name }}(args[{{ arg.jsArg }}]->ToString()); - from_{{ arg.name }} = ({{ arg.cType }}) strdup(*{{ arg.name }}); - {%elsif arg.cppClassName == 'Array' %} - Array *tmp_{{ arg.name }} = Array::Cast(*args[{{ arg.jsArg }}]); - from_{{ arg.name }} = ({{ arg.cType }})malloc(tmp_{{ arg.name }}->Length() * sizeof({{ arg.cType|replace '**' '*' }})); - for (unsigned int i = 0; i < tmp_{{ arg.name }}->Length(); i++) { + {%if cppClassName == 'String' %} + String::Utf8Value {{ name }}(args[{{ jsArg }}]->ToString()); + from_{{ name }} = ({{ cType }}) strdup(*{{ name }}); + {%elsif cppClassName == 'Array' %} + Array *tmp_{{ name }} = Array::Cast(*args[{{ jsArg }}]); + from_{{ name }} = ({{ cType }})malloc(tmp_{{ name }}->Length() * sizeof({{ cType|replace '**' '*' }})); + for (unsigned int i = 0; i < tmp_{{ name }}->Length(); i++) { {%-- // FIXME: should recursively call convertFromv8. --%} - from_{{ arg.name }}[i] = ObjectWrap::Unwrap<{{ arg.arrayElementCppClassName }}>(tmp_{{ arg.name }}->Get(NanNew(static_cast(i)))->ToObject())->GetValue(); + from_{{ name }}[i] = ObjectWrap::Unwrap<{{ arrayElementCppClassName }}>(tmp_{{ name }}->Get(NanNew(static_cast(i)))->ToObject())->GetValue(); } - {%elsif arg.cppClassName == 'Function' %} - {%elsif arg.cppClassName == 'Buffer' %} - from_{{ arg.name }} = Buffer::Data(args[{{ arg.jsArg }}]->ToObject()); - {%elsif arg.cppClassName|isV8Value %} - from_{{ arg.name }} = ({{ arg.cType }}) {{ arg.additionalCast }} {{ arg.cast }} args[{{ arg.jsArg }}]->To{{ arg.cppClassName }}()->Value(); + {%elsif cppClassName == 'Function' %} + {%elsif cppClassName == 'Buffer' %} + from_{{ name }} = Buffer::Data(args[{{ jsArg }}]->ToObject()); + {%elsif cppClassName|isV8Value %} + from_{{ name }} = ({{ cType }}) {{ additionalCast }} {{ cast }} args[{{ jsArg }}]->To{{ cppClassName }}()->Value(); {%else%} - from_{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args[{{ arg.jsArg }}]->ToObject())->GetValue(); + from_{{ name }} = ObjectWrap::Unwrap<{{ cppClassName }}>(args[{{ jsArg }}]->ToObject())->GetValue(); {%endif%} - {%if arg.isOptional %} + {%if isOptional %} } else { - from_{{ arg.name }} = 0; + from_{{ name }} = 0; } {%endif%}} {%endif%} diff --git a/generate/partials/convert_to_v8.cc b/generate/partials/convert_to_v8.cc index e69de29bb..c48d019d6 100644 --- a/generate/partials/convert_to_v8.cc +++ b/generate/partials/convert_to_v8.cc @@ -0,0 +1,39 @@ +{%if cppClassName == 'String' %} + {%if size %} +to = NanNew({{ parsedName }}, {{ size }}); + {%elsif cType == 'char **' %} +to = NanNew(*{{ parsedName }}); + {%else%}} +to = NanNew({{ parsedName }}); + {%endif%} + + {%if freeFunctionName %} + {{ freeFunctionName }}({{ parsedName }}); + {%endif%} +{%elsif cppClassName|isV8Value %} + {%if isCppClassIntType %} +to = NanNew<{{ cppClassName }}>(({{ parsedClassName }}){{ parsedName }}); + {%else%} +to = NanNew<{{ cppClassName }}>({{ parsedName }}); + {%endif%} +{%elsif cppClassName == 'External' %} +to = NanNew((void *){{ parsedName }}); +{%elsif cppClassName == 'Array' %} +{%-- // FIXME this is not general purpose enough. --%} +Local tmpArray = NanNew({{ parsedName }}->{{ size }}); +for (unsigned int i = 0; i < {{ parsedName }}->{{ size }}; i++) { + tmpArray->Set(NanNew(i), NanNew({{ parsedName }}->{{ key }}[i])); +} +to = tmpArray; +{%else%} + {%if copy %} +if ({{ parsedName }} != NULL) { + {{ parsedName }} = ({{ cType|replace '**' '*' }} {%if cType|isPointer %}*{%endif%}){{ copy }}({{ parsedName }}); +} + {%endif%} +if ({{ parsedName }} != NULL) { + to = {{ cppClassName }}::New((void *){{ parsedName }}); +} else { + to = NanNull(); +} +{%endif%} diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc index c4a632446..c43467482 100644 --- a/generate/partials/fields.cc +++ b/generate/partials/fields.cc @@ -1,16 +1,15 @@ -{%each fields as field%} - {%if not field.ignore%} +{%each fields|fieldsInfo as field %} + {%if not field.ignore %} NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { NanScope(); - <% var to = fieldInfo; -%> Handle to; - <%- fieldInfo.cType %> <% if (!isV8Value(fieldInfo.cppClassName)) { %>*<% } %><%- fieldInfo.name %> = - <% if (!isV8Value(fieldInfo.cppClassName)) { %>&<% } %>ObjectWrap::Unwrap<<%- cppClassName %>>(args.This())->GetValue()-><%- fieldInfo.name %>; + {{ field.cType }} {%if field.cppClassName|isV8Value %}*{%endif%}{{ field.name }} = + {%if not field.cppClassName|isV8Value %}&{%endif%}ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }}; - <% include convertToV8.cc.ejs -%> + {%partial convertToV8 field %} NanReturnValue(to); } -<% } -%> -<% } -%> + {%endif%} +{%endeach%} From 9e929cfb8ce43f4f845f5e12240f61b0de91ec8d Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 26 Sep 2014 17:55:37 -0700 Subject: [PATCH 13/34] Starting to work on sync_functions.cc --- generate/filters/args_info.js | 3 +- generate/index.js | 1 + generate/partials/sync_function.cc | 85 ++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/generate/filters/args_info.js b/generate/filters/args_info.js index 544f2ee11..0f77e1e77 100644 --- a/generate/filters/args_info.js +++ b/generate/filters/args_info.js @@ -21,9 +21,10 @@ module.exports = function(args) { else { arg.lastArg = false; } - + arg.cArg = cArg; arg.v8ValueClassName = cppToV8(arg.cppClassName); + arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); result.push(arg); } diff --git a/generate/index.js b/generate/index.js index 4533931b2..2676c6171 100644 --- a/generate/index.js +++ b/generate/index.js @@ -37,6 +37,7 @@ var filters = { isV8Value: require("./filters/is_v8_value"), isPointer: require("./filters/is_pointer"), isDoublePointer: require("./filters/is_double_pointer"), + unPointer: require("./filters/un_pointer"), hasReturnType: require("./filters/has_return_type"), convertReturns: require("./filters/convert_returns"), fieldsInfo: require("./filters/fields_info") diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index e69de29bb..991a5bdcd 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -0,0 +1,85 @@ +/** +{%partial doc .%} + */ +NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { + NanScope(); + {%partial guardArguments .%} + + {%each arg|argsInfo as arg %} + {%if not arg.isReturn %} + {%if arg.shouldAlloc %} + {{ arg.cType }}{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|unPointer }})); + {%else%} + {{ arg.cType|unPointer}} {{ arg.name }} = {{ arg.cType|unPointer|defaultValue }}; + {%endif%} + {%endif%} + {%endeach%} + + {%each args|argsInfo as arg %} + {%partial convertFromV8 arg %} + {%endeach%} + + {%if returns.length | or return.isErrorCode %} + {{ return.cType }} result = {%endif%}{{ cFunctionName }}( + {%each args|argsInfo as arg %} + {%if arg.isReturn %} + {%if not arg.shouldAlloc %} + & + {%endif%} + {%endif%} + {%if arg.isSelf %} +ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue() + {%elsif arg.isReturn %} +{{ arg.name }} + {%else%} +from_{{ arg.name }} + {%endif%} + {%if not arg.lastArg %},{%endif%} + {%endeach%} + ); + + {%each args|argsInfo as arg %} + {%if arg.isCppClassStringOrArray %} + {%if arg.freeFunctionName %} + {{ arg.freeFunctionName }}(from_{{ arg.name }}); + {%else%} + free((void *)from_{{ arg.name }}); + {%endif%} + {%endif%} + {%endeach%} + + {%if return.isErrorCode %} + if (result != GIT_OK) { + {%each args|argsInfo as arg %} + {%if arg.shouldAlloc %} + free(<%= arg.name %>); + {%endif%} + {%endeach%} + + if (giterr_last()) { + return NanThrowError(giterr_last()->message); + } else { + return NanThrowError("Unknown Error"); + } + } + {%endif%} + +{%if not returns.length %} + NanReturnUndefined(); +{%else%} + Handle to; + {%if returns.length > 1 %} + Handle toReturn = NanNew(); + {%endif%} + {%each returns|convertReturns as _return %} + {%partial convertToV8 _return %} + {%if returns.length > 1 %} + toReturn->Set(NanNew("{{ _return.jsName | or _return.name }}"), to); + {%endif%} + {%endeach%} + {%if returns.length == 1 %} + NanReturnValue(to); + {%else%} + NanReturnValue(toReturn); +{%endif%}} +} From e52b9c06321b77e13f3e51bc547bb76d3e712f7e Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 26 Sep 2014 17:56:07 -0700 Subject: [PATCH 14/34] Fixed an issue with the returns in the async function template --- generate/partials/async_function.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index efb22177d..972a5e720 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -76,20 +76,21 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { TryCatch try_catch; if (baton->error_code == GIT_OK) { {%if not returns.length %} - Handle result = NanUndefined(); + Handle result = NanUndefined(); {%else%} + Handle to; + {%if returns.length > 1 %} + Handle result = NanNew(); + {%endif%} {%each returns|convertReturns as _return %} - {%if returns.length == 1 %} - Handle to; - {%partial convertToV8 _return %} - Handle result = to; - {%else%} - Handle result = NanNew(); - Handle to; - {%partial convertToV8 _return %} - result->Set(NanNew("{{ _return.jsName | or _return.name }}"), to); + {%partial convertToV8 _return %} + {%if returns.length > 1 %} + result->Set(NanNew("{{ _return.jsName | or _return.name }}"), to); {%endif%} {%endeach%} + {%if returns.length == 1 %} + Handle result = to; + {%endif%} {%endif%} Handle argv[2] = { NanNull(), From 3c992e50fcde3c8554689d56755b6a5af93030ef Mon Sep 17 00:00:00 2001 From: John Haley Date: Mon, 29 Sep 2014 09:28:54 -0700 Subject: [PATCH 15/34] Fixing more bugs with the template build --- generate/filters/convert_returns.js | 23 +++++++---------------- generate/filters/js_args_count.js | 4 ++++ generate/index.js | 10 ++++++++++ generate/partials/async_function.cc | 2 +- generate/partials/sync_function.cc | 2 +- generate/templates/class.cc | 4 ++-- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/generate/filters/convert_returns.js b/generate/filters/convert_returns.js index 6dab7fbf9..2766f7dd2 100644 --- a/generate/filters/convert_returns.js +++ b/generate/filters/convert_returns.js @@ -1,24 +1,15 @@ module.exports = function(returns) { var result = []; - if (returns.length == 1) { - var singleReturn = {}; - singleReturn.__proto__ = returns[0]; - singleReturn.parsedName = "baton->" + to.name; - singleReturn.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(singleReturn.cppClassName); - singleReturn.parsedClassName = (singleReturn.cppClassName || '').toLowerCase() + "_t"; + returns.forEach(function (_return) { + _return.parsedName = returns.length === 1 ? "baton->" + _return.name : _return.name; + _return.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(_return.cppClassName); + _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; + _return.jsNameOrName = _return.jsName | _return.name; - result.push(singleReturn); - } - else { - returns.forEach(function (_return) { - _return.parsedName = _return.name; - _return.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(_return.cppClassName); - _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; - result.push(_return); - }); - } + result.push(_return); + }); return result; }; diff --git a/generate/filters/js_args_count.js b/generate/filters/js_args_count.js index 85bc3e76d..5be437f41 100644 --- a/generate/filters/js_args_count.js +++ b/generate/filters/js_args_count.js @@ -2,6 +2,10 @@ module.exports = function(args) { var cArg, jsArg; + if (!args) { + return 0; + } + for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { var arg = args[cArg]; diff --git a/generate/index.js b/generate/index.js index 2676c6171..cf8ea513a 100644 --- a/generate/index.js +++ b/generate/index.js @@ -63,6 +63,16 @@ Object.keys(partials).forEach(function(partial) { var enabled = idefs.filter(function(idef) { // Additionally provide a friendly name to the actual filename. idef.name = path.basename(idef.filename, ".h"); + + // Helper functions to allow partials to have access to custom data + idef.attachCommonData = function(partialData) { + var result; + + result.__proto__ = partialData; + result.cppClassName = idef.cppClassName; + + return result; + } return !idef.ignore; }); diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 972a5e720..d0db0765f 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -83,7 +83,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { Handle result = NanNew(); {%endif%} {%each returns|convertReturns as _return %} - {%partial convertToV8 _return %} + {%partial convertToV8 _return %} {%if returns.length > 1 %} result->Set(NanNew("{{ _return.jsName | or _return.name }}"), to); {%endif%} diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index 991a5bdcd..ca9a68025 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -74,7 +74,7 @@ from_{{ arg.name }} {%each returns|convertReturns as _return %} {%partial convertToV8 _return %} {%if returns.length > 1 %} - toReturn->Set(NanNew("{{ _return.jsName | or _return.name }}"), to); + toReturn->Set(NanNew("{{ _return.jsNameOrName }}"), to); {%endif%} {%endeach%} {%if returns.length == 1 %} diff --git a/generate/templates/class.cc b/generate/templates/class.cc index f65cf9c3c..593b218d0 100644 --- a/generate/templates/class.cc +++ b/generate/templates/class.cc @@ -94,9 +94,9 @@ void {{ cppClassName }}::Initialize(Handle target) { {%each functions as function%} {%if not function.ignore%} {%if function.isAsync%} - {%partial asyncFunction function%} + {%partial asyncFunction attachCommonData function%} {%else%} - {%partial syncFunction function%} + {%partial syncFunction attachCommonData function%} {%endif%} {%endif%} {%endeach%} From cac4c8cb8d937a959fbd5e116f4d78d4820cf077 Mon Sep 17 00:00:00 2001 From: John Haley Date: Mon, 29 Sep 2014 09:48:59 -0700 Subject: [PATCH 16/34] Templates build now --- generate/index.js | 3 ++- generate/partials/sync_function.cc | 28 ++++++++++++++++------------ generate/templates/class.cc | 4 ++-- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/generate/index.js b/generate/index.js index cf8ea513a..9c8ca3de9 100644 --- a/generate/index.js +++ b/generate/index.js @@ -70,7 +70,8 @@ var enabled = idefs.filter(function(idef) { result.__proto__ = partialData; result.cppClassName = idef.cppClassName; - + result.returns = idef.returns || []; + return result; } return !idef.ignore; diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index ca9a68025..74ffbaf90 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -19,6 +19,9 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%partial convertFromV8 arg %} {%endeach%} +{%if not returns %} + NanReturnUndefined(); +{%else%} {%if returns.length | or return.isErrorCode %} {{ return.cType }} result = {%endif%}{{ cFunctionName }}( {%each args|argsInfo as arg %} @@ -64,22 +67,23 @@ from_{{ arg.name }} } {%endif%} -{%if not returns.length %} + {%if not returns.length %} NanReturnUndefined(); -{%else%} + {%else%} Handle to; - {%if returns.length > 1 %} - Handle toReturn = NanNew(); - {%endif%} - {%each returns|convertReturns as _return %} - {%partial convertToV8 _return %} {%if returns.length > 1 %} - toReturn->Set(NanNew("{{ _return.jsNameOrName }}"), to); + Handle toReturn = NanNew(); {%endif%} - {%endeach%} - {%if returns.length == 1 %} + {%each returns|convertReturns as _return %} + {%partial convertToV8 _return %} + {%if returns.length > 1 %} + toReturn->Set(NanNew("{{ _return.jsNameOrName }}"), to); + {%endif%} + {%endeach%} + {%if returns.length == 1 %} NanReturnValue(to); - {%else%} + {%else%} NanReturnValue(toReturn); -{%endif%}} + {%endif%}} +{%endif%} } diff --git a/generate/templates/class.cc b/generate/templates/class.cc index 593b218d0..e971f7032 100644 --- a/generate/templates/class.cc +++ b/generate/templates/class.cc @@ -94,9 +94,9 @@ void {{ cppClassName }}::Initialize(Handle target) { {%each functions as function%} {%if not function.ignore%} {%if function.isAsync%} - {%partial asyncFunction attachCommonData function%} + {%partial asyncFunction attachCommonData function %} {%else%} - {%partial syncFunction attachCommonData function%} + {%partial syncFunction attachCommonData function %} {%endif%} {%endif%} {%endeach%} From a288308f7e653caf152bb29e061e02cff43b9160 Mon Sep 17 00:00:00 2001 From: John Haley Date: Mon, 29 Sep 2014 10:11:39 -0700 Subject: [PATCH 17/34] Fixed bug in header.h template --- generate/templates/header.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generate/templates/header.h b/generate/templates/header.h index 51772b31f..2f6a58e5b 100644 --- a/generate/templates/header.h +++ b/generate/templates/header.h @@ -1,5 +1,5 @@ -#ifndef {{ cppClassName.toUpperCase() }}_H -#define {{ cppClassName.toUpperCase() }}_H +#ifndef {{ cppClassName|upper }}_H +#define {{ cppClassName|upper }}_H #include #include @@ -82,7 +82,7 @@ class {{ cppClassName }} : public ObjectWrap { {{ function.cppFunctionName }}Baton *baton; }; {%endif%} - + static NAN_METHOD({{ function.cppFunctionName }}); {%endif%} {%endeach%} From 89cec609e40b038ad1c1556a7c15dcadfe4508b6 Mon Sep 17 00:00:00 2001 From: John Haley Date: Mon, 29 Sep 2014 14:14:23 -0700 Subject: [PATCH 18/34] More work on getting partials to have the right data --- generate/index.js | 16 +++---- generate/partials/async_function.cc | 8 ++-- generate/partials/doc.cc | 5 +- generate/partials/sync_function.cc | 72 ++++++++++++++--------------- generate/templates/class.cc | 6 +-- 5 files changed, 49 insertions(+), 58 deletions(-) diff --git a/generate/index.js b/generate/index.js index 9c8ca3de9..7862ee680 100644 --- a/generate/index.js +++ b/generate/index.js @@ -64,16 +64,14 @@ var enabled = idefs.filter(function(idef) { // Additionally provide a friendly name to the actual filename. idef.name = path.basename(idef.filename, ".h"); - // Helper functions to allow partials to have access to custom data - idef.attachCommonData = function(partialData) { - var result; - - result.__proto__ = partialData; - result.cppClassName = idef.cppClassName; - result.returns = idef.returns || []; + // We need some custom data on each of the functions + idef.functions.forEach(function(fn) { + fn.cppClassName = idef.cppClassName; + fn.returns = idef.returns || []; + fn.return = idef.return || {}; + fn.hasReturns = fn.returns.length || fn.return.isErrorCode; + }); - return result; - } return !idef.ignore; }); diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index d0db0765f..80c1c9de3 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -53,7 +53,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { {{ cFunctionName }}( {%-- Insert Function Arguments --%} {%each args|argsInfo as arg %} - {%-- turn the pointer into a ref %} + {%-- turn the pointer into a ref --%} {%if arg.isReturn|and arg.cType|isDoublePointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} {%endeach%} ); @@ -85,7 +85,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { {%each returns|convertReturns as _return %} {%partial convertToV8 _return %} {%if returns.length > 1 %} - result->Set(NanNew("{{ _return.jsName | or _return.name }}"), to); + result->Set(NanNew("{{ _return.jsNameOrName }}"), to); {%endif%} {%endeach%} {%if returns.length == 1 %} @@ -121,8 +121,8 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { node::FatalException(try_catch); } - {%each args as arg %} - {%if arg.cppClassName == 'String' | or arg.cppClassName == 'Array' %} + {%each args|argsInfo as arg %} + {%if arg.isCppClassStringOrArray %} {%if arg.freeFunctionName %} {{ arg.freeFunctionName }}(baton->{{ arg.name }}); {%else%} diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index f6e398986..50baeaa84 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -5,13 +5,10 @@ {%endif%} {%endif%} {%endeach%} - -{%-- -{%each .|returns as returnInfo %} +{%each returns|convertReturns as returnInfo %} {%if isAsync %} * @param {{ returnInfo.jsClassName }} callback {%else%} * @return {{ returnInfo.jsClassName }} {%if returnInfo.name %}{{ returnInfo.name }}{%else%}result{%endif%} {%endif%} {%endeach%} ---%} diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index 74ffbaf90..1ce46068a 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -19,45 +19,42 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%partial convertFromV8 arg %} {%endeach%} -{%if not returns %} - NanReturnUndefined(); -{%else%} - {%if returns.length | or return.isErrorCode %} +{%if hasReturns %} {{ return.cType }} result = {%endif%}{{ cFunctionName }}( - {%each args|argsInfo as arg %} - {%if arg.isReturn %} - {%if not arg.shouldAlloc %} + {%each args|argsInfo as arg %} + {%if arg.isReturn %} + {%if not arg.shouldAlloc %} & - {%endif%} {%endif%} - {%if arg.isSelf %} + {%endif%} + {%if arg.isSelf %} ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue() - {%elsif arg.isReturn %} + {%elsif arg.isReturn %} {{ arg.name }} - {%else%} + {%else%} from_{{ arg.name }} - {%endif%} - {%if not arg.lastArg %},{%endif%} - {%endeach%} + {%endif%} + {%if not arg.lastArg %},{%endif%} + {%endeach%} ); - {%each args|argsInfo as arg %} - {%if arg.isCppClassStringOrArray %} - {%if arg.freeFunctionName %} +{%each args|argsInfo as arg %} + {%if arg.isCppClassStringOrArray %} + {%if arg.freeFunctionName %} {{ arg.freeFunctionName }}(from_{{ arg.name }}); - {%else%} + {%else%} free((void *)from_{{ arg.name }}); - {%endif%} {%endif%} - {%endeach%} + {%endif%} +{%endeach%} - {%if return.isErrorCode %} +{%if return.isErrorCode %} if (result != GIT_OK) { - {%each args|argsInfo as arg %} + {%each args|argsInfo as arg %} {%if arg.shouldAlloc %} free(<%= arg.name %>); - {%endif%} - {%endeach%} + {%endif%} + {%endeach%} if (giterr_last()) { return NanThrowError(giterr_last()->message); @@ -65,25 +62,24 @@ from_{{ arg.name }} return NanThrowError("Unknown Error"); } } - {%endif%} +{%endif%} - {%if not returns.length %} +{%if not returns.length %} NanReturnUndefined(); - {%else%} +{%else%} Handle to; - {%if returns.length > 1 %} + {%if returns.length > 1 %} Handle toReturn = NanNew(); - {%endif%} - {%each returns|convertReturns as _return %} - {%partial convertToV8 _return %} - {%if returns.length > 1 %} + {%endif%} + {%each returns|convertReturns as _return %} + {%partial convertToV8 _return %} + {%if returns.length > 1 %} toReturn->Set(NanNew("{{ _return.jsNameOrName }}"), to); - {%endif%} - {%endeach%} - {%if returns.length == 1 %} + {%endif%} + {%endeach%} + {%if returns.length == 1 %} NanReturnValue(to); - {%else%} + {%else%} NanReturnValue(toReturn); - {%endif%}} -{%endif%} +{%endif%}} } diff --git a/generate/templates/class.cc b/generate/templates/class.cc index e971f7032..225340298 100644 --- a/generate/templates/class.cc +++ b/generate/templates/class.cc @@ -91,12 +91,12 @@ void {{ cppClassName }}::Initialize(Handle target) { } {%endif%} -{%each functions as function%} +{%each functions as function %} {%if not function.ignore%} {%if function.isAsync%} - {%partial asyncFunction attachCommonData function %} + {%partial asyncFunction function %} {%else%} - {%partial syncFunction attachCommonData function %} + {%partial syncFunction function %} {%endif%} {%endif%} {%endeach%} From 9c372361e425fecedb68650a6de42db339291a82 Mon Sep 17 00:00:00 2001 From: John Haley Date: Mon, 29 Sep 2014 15:50:20 -0700 Subject: [PATCH 19/34] Starting to make combyne templates 1:1 with ejs --- generate/filters/args_info.js | 33 ---------- generate/filters/convert_returns.js | 15 ----- generate/filters/fields_info.js | 11 ---- generate/filters/js_args_count.js | 18 ------ generate/filters/returns.js | 18 ------ generate/index.js | 91 +++++++++++++++++++++++++--- generate/partials/async_function.cc | 20 +++--- generate/partials/convert_from_v8.cc | 2 +- generate/partials/doc.cc | 6 +- generate/partials/fields.cc | 2 +- generate/partials/guard_arguments.cc | 4 +- generate/partials/sync_function.cc | 12 ++-- 12 files changed, 107 insertions(+), 125 deletions(-) delete mode 100644 generate/filters/args_info.js delete mode 100644 generate/filters/convert_returns.js delete mode 100644 generate/filters/fields_info.js delete mode 100644 generate/filters/js_args_count.js delete mode 100644 generate/filters/returns.js diff --git a/generate/filters/args_info.js b/generate/filters/args_info.js deleted file mode 100644 index 0f77e1e77..000000000 --- a/generate/filters/args_info.js +++ /dev/null @@ -1,33 +0,0 @@ -var cppToV8 = require("./cpp_to_v8"); - -module.exports = function(args) { - var result = [], - cArg, - jsArg; - - for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { - var arg = args[cArg]; - - if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { - arg.isJsArg = true; - arg.jsArg = jsArg; - - jsArg++; - } - - if (cArg >= args.length -1) { - arg.lastArg = true; - } - else { - arg.lastArg = false; - } - - arg.cArg = cArg; - arg.v8ValueClassName = cppToV8(arg.cppClassName); - arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); - - result.push(arg); - } - - return result; -}; diff --git a/generate/filters/convert_returns.js b/generate/filters/convert_returns.js deleted file mode 100644 index 2766f7dd2..000000000 --- a/generate/filters/convert_returns.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = function(returns) { - var result = []; - - - returns.forEach(function (_return) { - _return.parsedName = returns.length === 1 ? "baton->" + _return.name : _return.name; - _return.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(_return.cppClassName); - _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; - _return.jsNameOrName = _return.jsName | _return.name; - - result.push(_return); - }); - - return result; -}; diff --git a/generate/filters/fields_info.js b/generate/filters/fields_info.js deleted file mode 100644 index 64109e732..000000000 --- a/generate/filters/fields_info.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = function(fields) { - var result = []; - - fields.forEach(function (field){ - field.parsedName = field.name || "result"; - field.isCppClassIntType = ~["Uin32", "Int32"].indexOf(field.cppClassName); - field.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; - }); - - return result; -}; diff --git a/generate/filters/js_args_count.js b/generate/filters/js_args_count.js deleted file mode 100644 index 5be437f41..000000000 --- a/generate/filters/js_args_count.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = function(args) { - var cArg, - jsArg; - - if (!args) { - return 0; - } - - for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { - var arg = args[cArg]; - - if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { - jsArg++; - } - } - - return jsArg; -}; diff --git a/generate/filters/returns.js b/generate/filters/returns.js deleted file mode 100644 index 5e7505799..000000000 --- a/generate/filters/returns.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = function(functionInfo) { - var result = []; - - (functionInfo.args || []).forEach(function(arg) { - if (arg.isReturn) { - result.push(arg); - } - }); - - if (!result.length - && functionInfo.return - && !functionInfo.return.isErrorCode - && functionInfo.return.cType != "void"){ - result.push(functionInfo.return); - } - - return result; -}; diff --git a/generate/index.js b/generate/index.js index 7862ee680..a13de9283 100644 --- a/generate/index.js +++ b/generate/index.js @@ -2,6 +2,7 @@ const path = require("path"); const combyne = require("combyne"); const file = require("./util/file"); const idefs = require("./idefs"); +var cppToV8 = require("./filters/cpp_to_v8"); // Customize the delimiters so as to not process `{{{` or `}}}`. combyne.settings.delimiters = { @@ -31,16 +32,12 @@ var filters = { replace: require("./filters/replace"), or: require("./filters/or"), and: require("./filters/and"), - returns: require("./filters/returns"), - argsInfo: require("./filters/args_info"), - jsArgsCount: require("./filters/js_args_count"), isV8Value: require("./filters/is_v8_value"), isPointer: require("./filters/is_pointer"), isDoublePointer: require("./filters/is_double_pointer"), unPointer: require("./filters/un_pointer"), hasReturnType: require("./filters/has_return_type"), - convertReturns: require("./filters/convert_returns"), - fieldsInfo: require("./filters/fields_info") + defaultValue: require("./filters/default_value") }; // Convert Buffers to Combyne templates. @@ -67,9 +64,89 @@ var enabled = idefs.filter(function(idef) { // We need some custom data on each of the functions idef.functions.forEach(function(fn) { fn.cppClassName = idef.cppClassName; - fn.returns = idef.returns || []; - fn.return = idef.return || {}; + + // generate argument info + fn.args = fn.args || []; + fn.argsInfo = []; + + var cArg, + jsArg; + + for(cArg = 0, jsArg = 0; cArg < fn.args.length; cArg++) { + var arg = {}; + + arg.__proto__ = fn.args[cArg]; + + if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { + arg.isJsArg = true; + arg.jsArg = jsArg; + + jsArg++; + } + + if (cArg >= fn.args.length -1) { + arg.lastArg = true; + } + else { + arg.lastArg = false; + } + + arg.cArg = cArg; + arg.v8ValueClassName = cppToV8(arg.cppClassName); + arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); + + fn.argsInfo.push(arg); + } + + fn.jsArgsCount = jsArg; + + fn.returns = []; + + // generate returns data + fn.args.forEach(function(arg) { + if (!arg.isReturn) return; + + var _return = {}; + + _return.__proto__ = arg; + + _return.parsedName = _return.name; + _return.jsOrCppClassName = _return.jsClassName || _return.cppClassName; + _return.isCppClassIntType = ~["Uint32", "Int32"].indexOf(_return.cppClassName); + _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; + _return.jsNameOrName = _return.jsName | _return.name; + + fn.returns.push(_return); + }); + + fn.return = fn.return || {}; + + if (!fn.returns.length + && !fn.return.isErrorCode + && fn.return.cType != "void") { + fn.returns.push(fn.return); + } + + if (fn.returns.length === 1) { + fn.returns[0].parsedName = "baton->" + fn.returns[0].name; + } + fn.hasReturns = fn.returns.length || fn.return.isErrorCode; + + // generate fields data + fn.fields = fn.fields || []; + fn.fieldInfos = []; + + fn.fields.forEach(function (field) { + var fieldInfo = {}; + fieldInfo.__proto__ = field; + + fieldInfo.parsedName = field.name || "result"; + fieldInfo.isCppClassIntType = ~["Uin32", "Int32"].indexOf(field.cppClassName); + fieldInfo.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; + + fn.fieldInfos.push(fieldInfo); + }); }); return !idef.ignore; diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 80c1c9de3..28a7f879d 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -5,31 +5,31 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { NanScope(); {%partial guardArguments .%} - if (args.Length() == {{args|jsArgsCount}} || !args[{{args|jsArgsCount}}]->IsFunction()) { + if (args.Length() == {{ jsArgsCount }} || !args[{{ jsArgsCount }}]->IsFunction()) { return NanThrowError("Callback is required and must be a Function."); } {{ cppFunctionName }}Baton* baton = new {{ cppFunctionName }}Baton; baton->error_code = GIT_OK; baton->error = NULL; - {%each args|argsInfo as arg %} + {%each argsInfo as arg %} {%if not arg.isReturn %} {%if arg.isSelf %} baton->{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue(); - {%elsif arg.name $} + {%elsif arg.name %} {%partial convertFromV8 arg%} {%if not arg.isPayload %} baton->{{ arg.name }} = from_{{ arg.name }}; - {%endif} + {%endif%} {%endif%} {%elsif arg.shouldAlloc %} baton->{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|replace '*' '' }})); {%endif%} {%endeach%} - NanCallback *callback = new NanCallback(Local::Cast(args[{{args|jsArgsCount}}])); + NanCallback *callback = new NanCallback(Local::Cast(args[{{ jsArgsCount }}])); {{ cppFunctionName }}Worker *worker = new {{ cppFunctionName }}Worker(baton, callback); - {%each args|argsInfo as arg %} + {%each argsInfo as arg %} {%if not arg.isReturn %} {%if arg.isSelf %} worker->SaveToPersistent("{{ arg.name }}", args.This()); @@ -52,9 +52,9 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { {%endif%} {{ cFunctionName }}( {%-- Insert Function Arguments --%} - {%each args|argsInfo as arg %} + {%each argsInfo as arg %} {%-- turn the pointer into a ref --%} - {%if arg.isReturn|and arg.cType|isDoublePointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} + {%if arg.isReturn %}{%if arg.cType|isDoublePointer %}&{%endif%}{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} {%endeach%} ); @@ -82,7 +82,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { {%if returns.length > 1 %} Handle result = NanNew(); {%endif%} - {%each returns|convertReturns as _return %} + {%each returns as _return %} {%partial convertToV8 _return %} {%if returns.length > 1 %} result->Set(NanNew("{{ _return.jsNameOrName }}"), to); @@ -121,7 +121,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { node::FatalException(try_catch); } - {%each args|argsInfo as arg %} + {%each argsInfo as arg %} {%if arg.isCppClassStringOrArray %} {%if arg.freeFunctionName %} {{ arg.freeFunctionName }}(baton->{{ arg.name }}); diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc index e0b845495..025a1e87c 100644 --- a/generate/partials/convert_from_v8.cc +++ b/generate/partials/convert_from_v8.cc @@ -28,5 +28,5 @@ } else { from_{{ name }} = 0; } - {%endif%}} + {%endif%} {%endif%} diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index 50baeaa84..0169e2bf0 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -5,10 +5,10 @@ {%endif%} {%endif%} {%endeach%} -{%each returns|convertReturns as returnInfo %} +{%each returns as returnInfo %} {%if isAsync %} - * @param {{ returnInfo.jsClassName }} callback + * @param {{ returnInfo.jsOrCppClassName }} callback {%else%} - * @return {{ returnInfo.jsClassName }} {%if returnInfo.name %}{{ returnInfo.name }}{%else%}result{%endif%} + * @return {{ returnInfo.jsOrCppClassName }} {%if returnInfo.name %}{{ returnInfo.name }}{%else%}result{%endif%} {%endif%} {%endeach%} diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc index c43467482..42243388b 100644 --- a/generate/partials/fields.cc +++ b/generate/partials/fields.cc @@ -1,4 +1,4 @@ -{%each fields|fieldsInfo as field %} +{%each fieldInfos as field %} {%if not field.ignore %} NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { diff --git a/generate/partials/guard_arguments.cc b/generate/partials/guard_arguments.cc index 2cddb87d1..9927362a3 100644 --- a/generate/partials/guard_arguments.cc +++ b/generate/partials/guard_arguments.cc @@ -1,7 +1,7 @@ -{%each args|argsInfo as arg%} +{%each argsInfo as arg%} {%if arg.isJsArg%} {%if not arg.isOptional%} - if (args.Length() == {{arg.jsArg}} || !args[{{jsArg}}]->Is{{arg.v8ValueClassName}}()) { + if (args.Length() == {{arg.jsArg}} || !args[{{arg.jsArg}}]->Is{{arg.v8ValueClassName}}()) { return NanThrowError("{{arg.jsClassName}} {{arg.name}} is required."); } {%endif%} diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index 1ce46068a..505651bd5 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -5,7 +5,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { NanScope(); {%partial guardArguments .%} - {%each arg|argsInfo as arg %} + {%each argsInfo as arg %} {%if not arg.isReturn %} {%if arg.shouldAlloc %} {{ arg.cType }}{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|unPointer }})); @@ -15,13 +15,13 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%endif%} {%endeach%} - {%each args|argsInfo as arg %} + {%each argsInfo as arg %} {%partial convertFromV8 arg %} {%endeach%} {%if hasReturns %} {{ return.cType }} result = {%endif%}{{ cFunctionName }}( - {%each args|argsInfo as arg %} + {%each argsInfo as arg %} {%if arg.isReturn %} {%if not arg.shouldAlloc %} & @@ -38,7 +38,7 @@ from_{{ arg.name }} {%endeach%} ); -{%each args|argsInfo as arg %} +{%each argsInfo as arg %} {%if arg.isCppClassStringOrArray %} {%if arg.freeFunctionName %} {{ arg.freeFunctionName }}(from_{{ arg.name }}); @@ -50,7 +50,7 @@ from_{{ arg.name }} {%if return.isErrorCode %} if (result != GIT_OK) { - {%each args|argsInfo as arg %} + {%each argsInfo as arg %} {%if arg.shouldAlloc %} free(<%= arg.name %>); {%endif%} @@ -71,7 +71,7 @@ from_{{ arg.name }} {%if returns.length > 1 %} Handle toReturn = NanNew(); {%endif%} - {%each returns|convertReturns as _return %} + {%each returns as _return %} {%partial convertToV8 _return %} {%if returns.length > 1 %} toReturn->Set(NanNew("{{ _return.jsNameOrName }}"), to); From 10c213278b519f0a8c5c2e98c2874d915f5d857b Mon Sep 17 00:00:00 2001 From: John Haley Date: Mon, 29 Sep 2014 16:36:04 -0700 Subject: [PATCH 20/34] Getting close to template 1:1 --- generate/filters/has_return_type.js | 7 ------- generate/filters/is_double_pointer.js | 3 --- generate/filters/is_v8_value.js | 2 +- generate/index.js | 17 ++++++++++++--- generate/partials/async_function.cc | 6 ++---- generate/partials/convert_from_v8.cc | 2 +- generate/partials/convert_to_v8.cc | 30 +++++++++++++-------------- generate/partials/sync_function.cc | 6 +++--- 8 files changed, 36 insertions(+), 37 deletions(-) delete mode 100644 generate/filters/has_return_type.js delete mode 100644 generate/filters/is_double_pointer.js diff --git a/generate/filters/has_return_type.js b/generate/filters/has_return_type.js deleted file mode 100644 index 2d21a0e66..000000000 --- a/generate/filters/has_return_type.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = function(functionInfo) { - if (functionInfo.return) { - return functionInfo.return.cType != "void" || functionInfo.return.isErrorCode; - } - - return false; -}; diff --git a/generate/filters/is_double_pointer.js b/generate/filters/is_double_pointer.js deleted file mode 100644 index 9d1246ab4..000000000 --- a/generate/filters/is_double_pointer.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function(cType) { - return /\s*\*\*\s*/.test(cType); -}; diff --git a/generate/filters/is_v8_value.js b/generate/filters/is_v8_value.js index f773ff6a2..f99a13f59 100644 --- a/generate/filters/is_v8_value.js +++ b/generate/filters/is_v8_value.js @@ -10,5 +10,5 @@ var v8 = [ ]; module.exports = function(cppClassName) { - return v8.indexOf(cppClassName) > -1; + return v8.indexOf(cppClassName) > -1 ? true : false; }; diff --git a/generate/index.js b/generate/index.js index a13de9283..96da00b33 100644 --- a/generate/index.js +++ b/generate/index.js @@ -34,9 +34,7 @@ var filters = { and: require("./filters/and"), isV8Value: require("./filters/is_v8_value"), isPointer: require("./filters/is_pointer"), - isDoublePointer: require("./filters/is_double_pointer"), unPointer: require("./filters/un_pointer"), - hasReturnType: require("./filters/has_return_type"), defaultValue: require("./filters/default_value") }; @@ -70,7 +68,17 @@ var enabled = idefs.filter(function(idef) { fn.argsInfo = []; var cArg, - jsArg; + jsArg, + v8Values = [ + "Boolean", + "Number", + "String", + "Integer", + "Int32", + "Uint32", + "Date", + "Function" + ];; for(cArg = 0, jsArg = 0; cArg < fn.args.length; cArg++) { var arg = {}; @@ -94,6 +102,8 @@ var enabled = idefs.filter(function(idef) { arg.cArg = cArg; arg.v8ValueClassName = cppToV8(arg.cppClassName); arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); + arg.isDoublePointer = /\s*\*\*\s*/.test(arg.cType); + arg.isV8Value = ~v8Values.indexOf(arg.cppClassName); fn.argsInfo.push(arg); } @@ -132,6 +142,7 @@ var enabled = idefs.filter(function(idef) { } fn.hasReturns = fn.returns.length || fn.return.isErrorCode; + fn.hasReturnType = fn.return.cType != "void" || fn.return.isErrorCode; // generate fields data fn.fields = fn.fields || []; diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 28a7f879d..10677385a 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -35,9 +35,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { worker->SaveToPersistent("{{ arg.name }}", args.This()); {%else%} if (!args[{{ arg.jsArg }}]->IsUndefined() && !args[{{ arg.jsArg }}]->IsNull()) - { worker->SaveToPersistent("{{ arg.name }}", args[{{ arg.jsArg }}]->ToObject()); - } {%endif%} {%endif%} {%endeach%} @@ -47,14 +45,14 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { } void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { - {%if functionInfo|hasReturnType %} + {%if hasReturnType %} {{ return.cType }} result = {%endif%} {{ cFunctionName }}( {%-- Insert Function Arguments --%} {%each argsInfo as arg %} {%-- turn the pointer into a ref --%} - {%if arg.isReturn %}{%if arg.cType|isDoublePointer %}&{%endif%}{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} + {%if arg.isReturn %}{%if arg.isDoublePointer %}&{%endif%}{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} {%endeach%} ); diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc index 025a1e87c..6fecedb45 100644 --- a/generate/partials/convert_from_v8.cc +++ b/generate/partials/convert_from_v8.cc @@ -18,7 +18,7 @@ {%elsif cppClassName == 'Function' %} {%elsif cppClassName == 'Buffer' %} from_{{ name }} = Buffer::Data(args[{{ jsArg }}]->ToObject()); - {%elsif cppClassName|isV8Value %} + {%elsif isV8Value %} from_{{ name }} = ({{ cType }}) {{ additionalCast }} {{ cast }} args[{{ jsArg }}]->To{{ cppClassName }}()->Value(); {%else%} from_{{ name }} = ObjectWrap::Unwrap<{{ cppClassName }}>(args[{{ jsArg }}]->ToObject())->GetValue(); diff --git a/generate/partials/convert_to_v8.cc b/generate/partials/convert_to_v8.cc index c48d019d6..9b7d084f0 100644 --- a/generate/partials/convert_to_v8.cc +++ b/generate/partials/convert_to_v8.cc @@ -1,38 +1,38 @@ {%if cppClassName == 'String' %} {%if size %} -to = NanNew({{ parsedName }}, {{ size }}); +to = NanNew({{{ parsedName }}}, {{ size }}); {%elsif cType == 'char **' %} -to = NanNew(*{{ parsedName }}); - {%else%}} -to = NanNew({{ parsedName }}); +to = NanNew(*{{{ parsedName }}}); + {%else%} +to = NanNew({{{ parsedName }}}); {%endif%} {%if freeFunctionName %} - {{ freeFunctionName }}({{ parsedName }}); + {{ freeFunctionName }}({{{ parsedName }}}); {%endif%} {%elsif cppClassName|isV8Value %} {%if isCppClassIntType %} -to = NanNew<{{ cppClassName }}>(({{ parsedClassName }}){{ parsedName }}); +to = NanNew<{{ cppClassName }}>(({{ parsedClassName }}){{{ parsedName }}}); {%else%} -to = NanNew<{{ cppClassName }}>({{ parsedName }}); +to = NanNew<{{ cppClassName }}>({{{ parsedName }}}); {%endif%} {%elsif cppClassName == 'External' %} -to = NanNew((void *){{ parsedName }}); +to = NanNew((void *){{{ parsedName }}}); {%elsif cppClassName == 'Array' %} {%-- // FIXME this is not general purpose enough. --%} -Local tmpArray = NanNew({{ parsedName }}->{{ size }}); -for (unsigned int i = 0; i < {{ parsedName }}->{{ size }}; i++) { - tmpArray->Set(NanNew(i), NanNew({{ parsedName }}->{{ key }}[i])); +Local tmpArray = NanNew({{{ parsedName }}}->{{ size }}); +for (unsigned int i = 0; i < {{{ parsedName }}}->{{ size }}; i++) { + tmpArray->Set(NanNew(i), NanNew({{{ parsedName }}}->{{ key }}[i])); } to = tmpArray; {%else%} {%if copy %} -if ({{ parsedName }} != NULL) { - {{ parsedName }} = ({{ cType|replace '**' '*' }} {%if cType|isPointer %}*{%endif%}){{ copy }}({{ parsedName }}); +if ({{{ parsedName }}} != NULL) { + {{{ parsedName }}} = ({{ cType|replace '**' '*' }} {%if cType|isPointer %}*{%endif%}){{ copy }}({{{ parsedName }}}); } {%endif%} -if ({{ parsedName }} != NULL) { - to = {{ cppClassName }}::New((void *){{ parsedName }}); +if ({{{ parsedName }}} != NULL) { + to = {{ cppClassName }}::New((void *){{{ parsedName }}}); } else { to = NanNull(); } diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index 505651bd5..c6f4f5f97 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -6,11 +6,11 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%partial guardArguments .%} {%each argsInfo as arg %} - {%if not arg.isReturn %} + {%if arg.isReturn %} {%if arg.shouldAlloc %} {{ arg.cType }}{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|unPointer }})); {%else%} - {{ arg.cType|unPointer}} {{ arg.name }} = {{ arg.cType|unPointer|defaultValue }}; + {{ arg.cType|unPointer }} {{ arg.name }} = {{ arg.cType|unPointer|defaultValue }}; {%endif%} {%endif%} {%endeach%} @@ -81,5 +81,5 @@ from_{{ arg.name }} NanReturnValue(to); {%else%} NanReturnValue(toReturn); -{%endif%}} +{%endif%} } From e57b390579e0890f8e15e4882039baba620b58bb Mon Sep 17 00:00:00 2001 From: John Haley Date: Tue, 30 Sep 2014 10:10:23 -0700 Subject: [PATCH 21/34] Combyne templates are almost finished --- generate/filters/is_pointer.js | 3 --- generate/index.js | 23 ++++++++++++++++++++--- generate/partials/convert_from_v8.cc | 2 +- generate/partials/convert_to_v8.cc | 8 +++++--- generate/partials/fields.cc | 4 ++-- generate/partials/sync_function.cc | 1 + generate/templates/class.cc | 2 +- 7 files changed, 30 insertions(+), 13 deletions(-) delete mode 100644 generate/filters/is_pointer.js diff --git a/generate/filters/is_pointer.js b/generate/filters/is_pointer.js deleted file mode 100644 index a5dbb053e..000000000 --- a/generate/filters/is_pointer.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function(cType) { - return /\s*\*\s*/.test(cType); -}; diff --git a/generate/index.js b/generate/index.js index 96da00b33..48fb5bf22 100644 --- a/generate/index.js +++ b/generate/index.js @@ -33,7 +33,6 @@ var filters = { or: require("./filters/or"), and: require("./filters/and"), isV8Value: require("./filters/is_v8_value"), - isPointer: require("./filters/is_pointer"), unPointer: require("./filters/un_pointer"), defaultValue: require("./filters/default_value") }; @@ -58,7 +57,8 @@ Object.keys(partials).forEach(function(partial) { var enabled = idefs.filter(function(idef) { // Additionally provide a friendly name to the actual filename. idef.name = path.basename(idef.filename, ".h"); - + idef.cTypeIsUndefined = typeof idef.cType == 'undefined'; + // We need some custom data on each of the functions idef.functions.forEach(function(fn) { fn.cppClassName = idef.cppClassName; @@ -102,6 +102,7 @@ var enabled = idefs.filter(function(idef) { arg.cArg = cArg; arg.v8ValueClassName = cppToV8(arg.cppClassName); arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); + arg.isPointer = /\s*\*\s*/.test(arg.cType); arg.isDoublePointer = /\s*\*\*\s*/.test(arg.cType); arg.isV8Value = ~v8Values.indexOf(arg.cppClassName); @@ -113,7 +114,7 @@ var enabled = idefs.filter(function(idef) { fn.returns = []; // generate returns data - fn.args.forEach(function(arg) { + fn.argsInfo.forEach(function(arg) { if (!arg.isReturn) return; var _return = {}; @@ -134,6 +135,21 @@ var enabled = idefs.filter(function(idef) { if (!fn.returns.length && !fn.return.isErrorCode && fn.return.cType != "void") { + var _return = {}; + + _return = fn.return; + + _return.v8ValueClassName = cppToV8(_return.cppClassName); + _return.isCppClassStringOrArray = ~["String", "Array"].indexOf(_return.cppClassName); + _return.isPointer = /\s*\*\s*/.test(_return.cType); + _return.isDoublePointer = /\s*\*\*\s*/.test(_return.cType); + _return.isV8Value = ~v8Values.indexOf(_return.cppClassName); + _return.parsedName = 'result'; + _return.jsOrCppClassName = _return.jsClassName || _return.cppClassName; + _return.isCppClassIntType = ~["Uint32", "Int32"].indexOf(_return.cppClassName); + _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; + _return.jsNameOrName = _return.jsName | _return.name; + fn.returns.push(fn.return); } @@ -155,6 +171,7 @@ var enabled = idefs.filter(function(idef) { fieldInfo.parsedName = field.name || "result"; fieldInfo.isCppClassIntType = ~["Uin32", "Int32"].indexOf(field.cppClassName); fieldInfo.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; + fieldInfo.isV8Value = ~v8Values.indexOf(field.cppClassName); fn.fieldInfos.push(fieldInfo); }); diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc index 6fecedb45..58fc1eb9e 100644 --- a/generate/partials/convert_from_v8.cc +++ b/generate/partials/convert_from_v8.cc @@ -1,7 +1,7 @@ {%if not isPayload %} {{ cType }} from_{{ name }}; {%if isOptional %} - if (args{{[ jsArg }}]->Is{{ v8ValueClassName }}()) { + if (args[{{ jsArg }}]->Is{{ v8ValueClassName }}()) { {%endif%} {%if cppClassName == 'String' %} String::Utf8Value {{ name }}(args[{{ jsArg }}]->ToString()); diff --git a/generate/partials/convert_to_v8.cc b/generate/partials/convert_to_v8.cc index 9b7d084f0..f67e38860 100644 --- a/generate/partials/convert_to_v8.cc +++ b/generate/partials/convert_to_v8.cc @@ -10,7 +10,7 @@ to = NanNew({{{ parsedName }}}); {%if freeFunctionName %} {{ freeFunctionName }}({{{ parsedName }}}); {%endif%} -{%elsif cppClassName|isV8Value %} +{%elsif isV8Value %} {%if isCppClassIntType %} to = NanNew<{{ cppClassName }}>(({{ parsedClassName }}){{{ parsedName }}}); {%else%} @@ -19,7 +19,9 @@ to = NanNew<{{ cppClassName }}>({{{ parsedName }}}); {%elsif cppClassName == 'External' %} to = NanNew((void *){{{ parsedName }}}); {%elsif cppClassName == 'Array' %} -{%-- // FIXME this is not general purpose enough. --%} +{%-- + // FIXME this is not general purpose enough. +--%} Local tmpArray = NanNew({{{ parsedName }}}->{{ size }}); for (unsigned int i = 0; i < {{{ parsedName }}}->{{ size }}; i++) { tmpArray->Set(NanNew(i), NanNew({{{ parsedName }}}->{{ key }}[i])); @@ -28,7 +30,7 @@ to = tmpArray; {%else%} {%if copy %} if ({{{ parsedName }}} != NULL) { - {{{ parsedName }}} = ({{ cType|replace '**' '*' }} {%if cType|isPointer %}*{%endif%}){{ copy }}({{{ parsedName }}}); + {{{ parsedName }}} = ({{ cType|replace '**' '*' }} {%if isPointer %}*{%endif%}){{ copy }}({{{ parsedName }}}); } {%endif%} if ({{{ parsedName }}} != NULL) { diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc index 42243388b..1ee5e9406 100644 --- a/generate/partials/fields.cc +++ b/generate/partials/fields.cc @@ -5,8 +5,8 @@ NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { NanScope(); Handle to; - {{ field.cType }} {%if field.cppClassName|isV8Value %}*{%endif%}{{ field.name }} = - {%if not field.cppClassName|isV8Value %}&{%endif%}ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }}; + {{ field.cType }} {%if field.isV8Value %}*{%endif%}{{ field.name }} = + {%if not field.isV8Value %}&{%endif%}ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }}; {%partial convertToV8 field %} NanReturnValue(to); diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index c6f4f5f97..e34695bef 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -81,5 +81,6 @@ from_{{ arg.name }} NanReturnValue(to); {%else%} NanReturnValue(toReturn); + {%endif%} {%endif%} } diff --git a/generate/templates/class.cc b/generate/templates/class.cc index 225340298..2456ae3ef 100644 --- a/generate/templates/class.cc +++ b/generate/templates/class.cc @@ -103,6 +103,6 @@ void {{ cppClassName }}::Initialize(Handle target) { {%partial fields .%} -{%if cType%} +{%if not cTypeIsUndefined %} Persistent {{ cppClassName }}::constructor_template; {%endif%} From 415e22a241d32d74ae74a5c7511bfe9db8969f44 Mon Sep 17 00:00:00 2001 From: John Haley Date: Tue, 30 Sep 2014 13:26:49 -0700 Subject: [PATCH 22/34] Fixed sync_function.cc calling convertFromV8 for returns and self vars --- generate/partials/sync_function.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index e34695bef..f8b31d965 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -16,7 +16,11 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%endeach%} {%each argsInfo as arg %} - {%partial convertFromV8 arg %} + {%if not arg.isSelf %} + {%if not arg.isReturn %} + {%partial convertFromV8 arg %} + {%endif%} + {%endif%} {%endeach%} {%if hasReturns %} From ff17f1c5836c00a857d42daeebb790d90abf90ec Mon Sep 17 00:00:00 2001 From: John Haley Date: Tue, 30 Sep 2014 13:43:10 -0700 Subject: [PATCH 23/34] Removed ejs template files --- generate/partials/asyncFunction.cc.ejs | 140 --------------------- generate/partials/convertFromV8.cc.ejs | 31 ----- generate/partials/convertToV8.cc.ejs | 43 ------- generate/partials/doc.cc.ejs | 14 --- generate/partials/fields.cc.ejs | 20 --- generate/partials/guardArguments.cc.ejs | 13 -- generate/partials/syncFunction.cc.ejs | 95 -------------- generate/templates/class.cc.ejs | 160 ------------------------ 8 files changed, 516 deletions(-) delete mode 100644 generate/partials/asyncFunction.cc.ejs delete mode 100644 generate/partials/convertFromV8.cc.ejs delete mode 100644 generate/partials/convertToV8.cc.ejs delete mode 100644 generate/partials/doc.cc.ejs delete mode 100644 generate/partials/fields.cc.ejs delete mode 100644 generate/partials/guardArguments.cc.ejs delete mode 100644 generate/partials/syncFunction.cc.ejs delete mode 100644 generate/templates/class.cc.ejs diff --git a/generate/partials/asyncFunction.cc.ejs b/generate/partials/asyncFunction.cc.ejs deleted file mode 100644 index 48489a388..000000000 --- a/generate/partials/asyncFunction.cc.ejs +++ /dev/null @@ -1,140 +0,0 @@ -/** -<% include doc.cc.ejs -%> - */ -NAN_METHOD(<%- cppClassName %>::<%- functionInfo.cppFunctionName %>) { - NanScope(); - <% var jsArg; -%> - <% include guardArguments.cc.ejs -%> - - if (args.Length() == <%- jsArg %> || !args[<%- jsArg %>]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - <%- functionInfo.cppFunctionName %>Baton* baton = new <%- functionInfo.cppFunctionName %>Baton; - baton->error_code = GIT_OK; - baton->error = NULL; -<% - for (var cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; --%> -<% if (!arg.isReturn) { -%> -<% if (arg.isSelf) { -%> - baton-><%- arg.name %> = ObjectWrap::Unwrap<<%- arg.cppClassName %>>(args.This())->GetValue(); -<% } else if (arg.name) { -%> - <% include convertFromV8.cc.ejs -%> - <% if (!arg.isPayload) { -%> - baton-><%- arg.name %> = from_<%- arg.name %>; - <% } -%> -<% } -%> -<% if (!(arg.isReturn || arg.isSelf || arg.isPayload)) jsArg++; -%> -<% } else { -%> -<% if (arg.shouldAlloc) { -%> - baton-><%- arg.name %> = (<%- arg.cType %>)malloc(sizeof(<%- arg.cType.replace('*', '') %>)); -<% } -%> -<% } -%> -<% } -%> - - NanCallback *callback = new NanCallback(Local::Cast(args[<%- jsArg %>])); - <%- functionInfo.cppFunctionName %>Worker *worker = new <%- functionInfo.cppFunctionName %>Worker(baton, callback); -<% - for (var cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; --%> -<% if (!arg.isReturn) { -%> -<% if (arg.isSelf) { -%> - worker->SaveToPersistent("<%- arg.name %>", args.This()); -<% } else { -%> - if (!args[<%- jsArg %>]->IsUndefined() && !args[<%- jsArg %>]->IsNull()) - worker->SaveToPersistent("<%- arg.name %>", args[<%- jsArg %>]->ToObject()); -<% } -%> -<% if (!(arg.isReturn || arg.isSelf || arg.isPayload)) jsArg++; -%> -<% } -%> -<% } -%> - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void <%- cppClassName %>::<%- functionInfo.cppFunctionName %>Worker::Execute() { - <% if (functionInfo.return.cType != "void" || functionInfo.return.isErrorCode) { %><%- functionInfo.return.cType %> result = <% } %><%- functionInfo.cFunctionName %>( -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; --%> - <% if (arg.isReturn && /\*\*/.test(arg.cType)) { %>&<% } %>baton-><%- arg.name %><% if (i < functionInfo.args.length - 1) { %>, <% } %> -<% } -%> - ); -<% if (functionInfo.return.isErrorCode) { -%> - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -<% } else if (functionInfo.return.cType != "void") { -%> - baton->result = result; -<% } -%> -} - -void <%- cppClassName %>::<%- functionInfo.cppFunctionName %>Worker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { -<% if (!returns.length) { -%> - Handle result = NanUndefined(); -<% } else if (returns.length == 1) { -%> -<% var to = {}; to.__proto__ = returns[0]; to.name = "baton->" + to.name; -%> - Handle to; - <% include convertToV8.cc.ejs -%> - Handle result = to; -<% } else { -%> - Handle result = NanNew(); - Handle to; -<% - for (r in returns) { - var to = returns[r]; --%> - <% include convertToV8.cc.ejs -%> - result->Set(NanNew("<%- to.jsName || to.name %>"), to); -<% } -%> -<% } -%> - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - <% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (!arg.shouldAlloc) continue; - -%> - free(baton-><%= arg.name %>); - <% } -%> - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; --%> -<% if (['String', 'Array'].indexOf(arg.cppClassName) > -1) { -%> -<% if (arg.freeFunctionName) { %> - <%- arg.freeFunctionName %>(baton-><%- arg.name %>); -<% } else { -%> - free((void *)baton-><%- arg.name %>); -<% } -%> -<% } -%> -<% } -%> - delete baton; -} diff --git a/generate/partials/convertFromV8.cc.ejs b/generate/partials/convertFromV8.cc.ejs deleted file mode 100644 index d442377f9..000000000 --- a/generate/partials/convertFromV8.cc.ejs +++ /dev/null @@ -1,31 +0,0 @@ -<% if (!arg.isPayload) { -%> - <%- arg.cType %> from_<%- arg.name %>; - <% if (arg.isOptional) { -%> - if (args[<%- jsArg %>]->Is<%- cppClassName2v8ValueClassName(arg.cppClassName) %>()) { - <% } -%> - <% if (arg.cppClassName == 'String') { -%> - String::Utf8Value <%- arg.name %>(args[<%- jsArg %>]->ToString()); - from_<%- arg.name %> = (<%- arg.cType %>) strdup(*<%- arg.name %>); - <% } else if (arg.cppClassName == 'Array') { -%> - Array *tmp_<%- arg.name %> = Array::Cast(*args[<%- jsArg %>]); - from_<%- arg.name %> = (<%- arg.cType %>)malloc(tmp_<%- arg.name %>->Length() * sizeof(<%- arg.cType.replace('**', '*') %>)); - for (unsigned int i = 0; i < tmp_<%- arg.name %>->Length(); i++) { - <% - // FIXME: should recursively call convertFromv8. - %> - from_<%- arg.name %>[i] = ObjectWrap::Unwrap<<%- arg.arrayElementCppClassName %>>(tmp_<%- arg.name %>->Get(NanNew(static_cast(i)))->ToObject())->GetValue(); - } - <% } else if (arg.cppClassName == "Function") { -%> - <% } else if (arg.cppClassName == 'Buffer') { -%> - from_<%- arg.name %> = Buffer::Data(args[<%- jsArg %>]->ToObject()); - <% } else if (isV8Value(arg.cppClassName)) { -%> - from_<%- arg.name %> = (<%- arg.cType %>) <%- arg.additionalCast %> <%- arg.cast %> args[<%- jsArg %>]->To<%- arg.cppClassName %>()->Value(); - <% } else { -%> - from_<%- arg.name %> = ObjectWrap::Unwrap<<%- arg.cppClassName %>>(args[<%- jsArg %>]->ToObject())->GetValue(); - <% } -%> - <% if (arg.isOptional) { -%> - } else { - from_<%- arg.name %> = 0; - } - <% } -%> -<% } -%> diff --git a/generate/partials/convertToV8.cc.ejs b/generate/partials/convertToV8.cc.ejs deleted file mode 100644 index 7047d1db7..000000000 --- a/generate/partials/convertToV8.cc.ejs +++ /dev/null @@ -1,43 +0,0 @@ -<% toName = to.name || 'result' -%> -<% if (to.cppClassName == "String") { -%> - <% if (typeof to.size != 'undefined') { -%> -to = NanNew(<%- toName %>, <%- to.size %>); - <% } else if (to.cType === "char **") { -%> -to = NanNew(*<%- toName %>); - <% } else { -%> -to = NanNew(<%- toName %>); - <% } -%> - - <% if (to.freeFunctionName) { -%> - <%- to.freeFunctionName %>(<%- toName %>); - <% } -%> -<% } else if (isV8Value(to.cppClassName)) { -%> -<% if (~['Uint32', 'Int32'].indexOf(to.cppClassName)) { -%> -<% var className = to.cppClassName.toLowerCase()+'_t' -%> - to = NanNew<<%- to.cppClassName %>>((<%- className %>)<%- toName %>); -<% } else { -%> - to = NanNew<<%- to.cppClassName %>>(<%- toName %>); -<% } -%> -<% } else if (to.cppClassName == "External") { -%> - to = NanNew((void *)<%- toName %>); -<% } else if (to.cppClassName == 'Array') { -%> -<% - // FIXME this is not general purpose enough. -%> - Local tmpArray = NanNew(<%- toName %>-><%- to.size %>); - for (unsigned int i = 0; i < <%- toName %>-><%- to.size %>; i++) { - tmpArray->Set(NanNew(i), NanNew(<%- toName %>-><%- to.key %>[i])); - } - to = tmpArray; -<% } else { -%> -<% if (to.copy) { -%> - if (<%- toName %> != NULL) { - <%- toName %> = (<%- to.cType.replace('**', '*') %> <% if (!/\*/.test(to.cType)) {%>*<% } %>)<%- to.copy %>(<%- toName %>); - } -<% } -%> - if (<%- toName %> != NULL) { - to = <%- to.cppClassName %>::New((void *)<%- toName %>); - } else { - to = NanNull(); - } -<% } -%> diff --git a/generate/partials/doc.cc.ejs b/generate/partials/doc.cc.ejs deleted file mode 100644 index 44ca0979a..000000000 --- a/generate/partials/doc.cc.ejs +++ /dev/null @@ -1,14 +0,0 @@ -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (arg.isReturn || arg.isSelf) continue; --%> - * @param {<%- arg.jsClassName %>} <%- arg.name %> -<% } -%> -<% for (var r = 0; r < returns.length; r++) { -%> -<% if (functionInfo.isAsync) { -%> - * @param {<%- returns[r].jsClassName || returns[r].cppClassName %>} callback -<% } else { -%> - * @return {<%- returns[r].jsClassName || returns[r].cppClassName %>} <%- returns[r].name || 'result' %> -<% } -%> -<% } -%> diff --git a/generate/partials/fields.cc.ejs b/generate/partials/fields.cc.ejs deleted file mode 100644 index f7f684a99..000000000 --- a/generate/partials/fields.cc.ejs +++ /dev/null @@ -1,20 +0,0 @@ -<% if (typeof fields != 'undefined') { -%> -<% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore) continue; --%> - -NAN_METHOD(<%- cppClassName %>::<%- fieldInfo.cppFunctionName %>) { - NanScope(); - <% var to = fieldInfo; -%> - Handle to; - - <%- fieldInfo.cType %> <% if (!isV8Value(fieldInfo.cppClassName)) { %>*<% } %><%- fieldInfo.name %> = - <% if (!isV8Value(fieldInfo.cppClassName)) { %>&<% } %>ObjectWrap::Unwrap<<%- cppClassName %>>(args.This())->GetValue()-><%- fieldInfo.name %>; - - <% include convertToV8.cc.ejs -%> - NanReturnValue(to); -} -<% } -%> -<% } -%> diff --git a/generate/partials/guardArguments.cc.ejs b/generate/partials/guardArguments.cc.ejs deleted file mode 100644 index 99a99fb0f..000000000 --- a/generate/partials/guardArguments.cc.ejs +++ /dev/null @@ -1,13 +0,0 @@ -<% - var cArg = 0; - for (cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; - if (arg.isReturn || arg.isSelf || arg.isPayload) continue; --%> -<% if (!arg.isOptional) { -%> - if (args.Length() == <%- jsArg %> || !args[<%- jsArg %>]->Is<%- cppClassName2v8ValueClassName(arg.cppClassName) %>()) { - return NanThrowError("<%- arg.jsClassName %> <%- arg.name %> is required."); - } -<% } -%> -<% jsArg++; -%> -<% } -%> diff --git a/generate/partials/syncFunction.cc.ejs b/generate/partials/syncFunction.cc.ejs deleted file mode 100644 index 5f37e1094..000000000 --- a/generate/partials/syncFunction.cc.ejs +++ /dev/null @@ -1,95 +0,0 @@ -/** -<% include doc.cc.ejs -%> - */ -NAN_METHOD(<%- cppClassName %>::<%- functionInfo.cppFunctionName %>) { - NanScope(); - <% include guardArguments.cc.ejs -%> - -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (!arg.isReturn) continue; --%> -<% if (arg.shouldAlloc) { -%> - <%- arg.cType %><%- arg.name %> = (<%- arg.cType %>)malloc(sizeof(<%- unPointer(arg.cType) %>)); -<% } else { -%> - <%- unPointer(arg.cType) %> <%- arg.name %> = <%- defaultValue(unPointer(arg.cType)) %>; -<% } -%> -<% } -%> -<% - for (var cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; - if (arg.isSelf || arg.isReturn || arg.isPayload) continue; --%> -<% include convertFromV8.cc.ejs -%> -<% jsArg++; -%> -<% } %> - <% if (returns.length || functionInfo.return.isErrorCode) { %><%- functionInfo.return.cType %> result = <% } %><%- functionInfo.cFunctionName %>( -<% - for (var cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; --%> - <% if (cArg > 0) { %>, <% } -%><% if (arg.isReturn && !arg.shouldAlloc) { %>&<% } -%> -<% if (arg.isSelf) { -%> -ObjectWrap::Unwrap<<%- arg.cppClassName %>>(args.This())->GetValue() -<% } else if (arg.isReturn) { -%> -<%- arg.name %> -<% } else { -%> -from_<%- arg.name %> -<% } -%> -<% - if (!(arg.isReturn || arg.isSelf)) jsArg++; - } --%> - ); -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (arg.isSelf || arg.isReturn) continue; --%> -<% if (['String', 'Array'].indexOf(arg.cppClassName) > -1) { -%> -<% if (arg.freeFunctionName) { %> - <%- arg.freeFunctionName %>(from_<%- arg.name %>); -<% } else { -%> - free((void *)from_<%- arg.name %>); -<% } -%> -<% } -%> -<% } -%> -<% if (functionInfo.return.isErrorCode) { -%> - if (result != GIT_OK) { -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (!arg.shouldAlloc) continue; --%> - free(<%= arg.name %>); -<% } -%> - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } -<% } -%> - -<% if (!returns.length) { -%> - NanReturnUndefined(); -<% } else if (returns.length == 1) { -%> -<% var to = returns[0]; -%> - Handle to; - <% include convertToV8.cc.ejs -%> - NanReturnValue(to); -<% } else { -%> - Handle toReturn = NanNew(); - Handle to; -<% - for (r in returns) { - var to = returns[r]; --%> - <% include convertToV8.cc.ejs -%> - toReturn->Set(NanNew("<%- to.jsName || to.name %>"), to); - -<% } -%> - NanReturnValue(toReturn); -<% } -%> -} diff --git a/generate/templates/class.cc.ejs b/generate/templates/class.cc.ejs deleted file mode 100644 index 83c8b5f03..000000000 --- a/generate/templates/class.cc.ejs +++ /dev/null @@ -1,160 +0,0 @@ -<% - function isV8Value(cppClassName) { - return ["Boolean", "Number", "String", "Integer", "Int32", "Uint32", "Date", "Function"].indexOf(cppClassName) > -1; - } - - function cppClassName2v8ValueClassName(cppClassName) { - if (isV8Value(cppClassName)) - return cppClassName; - else - return 'Object'; - } - - function isPointer(cType) { - return /\s*\*\s*$/.test(cType); - } - - function unPointer(cType) { - return cType.replace(/\s*\*\s*$/,''); - } - - function defaultValue(cType) { - if (cType === 'git_otype') { return 'GIT_OBJ_ANY'; } - else { return '0'; } - } --%> -// This is a generated file, modify: generate/templates/class.cc.ejs. -#include -#include - -extern "C" { -#include -} - -#include "../include/functions/copy.h" -#include "../include/<%= filename %>" -<% if (typeof dependencies != 'undefined') { -%> -<% for (d in dependencies) { -%> -#include "<%- dependencies[d] %>" -<% } -%> -<% } -%> - -using namespace v8; -using namespace node; - -<% if (cType != undefined) { -%> -<%- cppClassName %>::<%- cppClassName %>(<%- cType %> *raw) { - this->raw = raw; -} - -<%- cppClassName %>::~<%- cppClassName %>() { -<% if (typeof freeFunctionName != 'undefined') { -%> - <%- freeFunctionName %>(this->raw); -<% } -%> -} - -void <%- cppClassName %>::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("<%- jsClassName %>")); - -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore) continue; --%> -<% if (functionInfo.isPrototypeMethod) { -%> - NODE_SET_PROTOTYPE_METHOD(tpl, "<%- functionInfo.jsFunctionName %>", <%- functionInfo.cppFunctionName %>); -<% } else { -%> - NODE_SET_METHOD(tpl, "<%- functionInfo.jsFunctionName %>", <%- functionInfo.cppFunctionName %>); -<% } -%> -<% } -%> -<% } -%> - -<% if (typeof fields != 'undefined') { -%> -<% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore) continue; --%> - NODE_SET_PROTOTYPE_METHOD(tpl, "<%- fieldInfo.jsFunctionName %>", <%- fieldInfo.cppFunctionName %>); -<% } -%> -<% } -%> - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("<%- jsClassName %>"), _constructor_template); -} - -NAN_METHOD(<%- cppClassName %>::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("<%= cType %> is required."); - } - <%- cppClassName %>* object = new <%- cppClassName %>(static_cast<<%= cType%> *>(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle <%- cppClassName %>::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(<%- cppClassName %>::constructor_template)->NewInstance(1, argv)); -} - -<%- cType %> *<%- cppClassName %>::GetValue() { - return this->raw; -} -<% } else { -%> -void <%- cppClassName %>::Initialize(Handle target) { - NanScope(); - - Local object = NanNew(); - -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore) continue; --%> - NODE_SET_METHOD(object, "<%- functionInfo.jsFunctionName %>", <%- functionInfo.cppFunctionName %>); -<% } -%> -<% } -%> - - target->Set(NanNew("<%- jsClassName %>"), object); -} -<% } -%> - -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore) continue; - - var returns = []; - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (arg.isReturn) returns.push(arg); - } - functionInfo.return = functionInfo.return || {}; - if (!returns.length && !functionInfo.return.isErrorCode && functionInfo.return.cType != "void") returns.push(functionInfo.return); --%> - -<% if (functionInfo.isAsync) { -%> -<% include generate/templates/asyncFunction.cc.ejs -%> -<% } else { -%> -<% include generate/templates/syncFunction.cc.ejs -%> -<% } -%> -<% } -%> -<% } -%> -<% include generate/templates/fields.cc.ejs -%> - -<% if (typeof cType != 'undefined') { -%> -Persistent <%- cppClassName %>::constructor_template; -<% } -%> From 6b30987145e27929be47aaeb16a796f98190d47c Mon Sep 17 00:00:00 2001 From: John Haley Date: Thu, 2 Oct 2014 11:39:45 -0700 Subject: [PATCH 24/34] More fixes to generated files --- generate/index.js | 4 ++-- generate/partials/convert_to_v8.cc | 28 ++++++++++++++-------------- generate/partials/sync_function.cc | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/generate/index.js b/generate/index.js index 48fb5bf22..9cb1de44b 100644 --- a/generate/index.js +++ b/generate/index.js @@ -58,7 +58,7 @@ var enabled = idefs.filter(function(idef) { // Additionally provide a friendly name to the actual filename. idef.name = path.basename(idef.filename, ".h"); idef.cTypeIsUndefined = typeof idef.cType == 'undefined'; - + // We need some custom data on each of the functions idef.functions.forEach(function(fn) { fn.cppClassName = idef.cppClassName; @@ -154,7 +154,7 @@ var enabled = idefs.filter(function(idef) { } if (fn.returns.length === 1) { - fn.returns[0].parsedName = "baton->" + fn.returns[0].name; + fn.returns[0].parsedName = fn.returns[0].name ? "baton->" + fn.returns[0].name : "result"; } fn.hasReturns = fn.returns.length || fn.return.isErrorCode; diff --git a/generate/partials/convert_to_v8.cc b/generate/partials/convert_to_v8.cc index f67e38860..7e527d218 100644 --- a/generate/partials/convert_to_v8.cc +++ b/generate/partials/convert_to_v8.cc @@ -1,40 +1,40 @@ {%if cppClassName == 'String' %} {%if size %} -to = NanNew({{{ parsedName }}}, {{ size }}); +to = NanNew({{= parsedName =}}, {{ size }}); {%elsif cType == 'char **' %} -to = NanNew(*{{{ parsedName }}}); +to = NanNew(*{{= parsedName =}}); {%else%} -to = NanNew({{{ parsedName }}}); +to = NanNew({{= parsedName =}}); {%endif%} {%if freeFunctionName %} - {{ freeFunctionName }}({{{ parsedName }}}); + {{ freeFunctionName }}({{= parsedName =}}); {%endif%} {%elsif isV8Value %} {%if isCppClassIntType %} -to = NanNew<{{ cppClassName }}>(({{ parsedClassName }}){{{ parsedName }}}); +to = NanNew<{{ cppClassName }}>(({{ parsedClassName }}){{= parsedName =}}); {%else%} -to = NanNew<{{ cppClassName }}>({{{ parsedName }}}); +to = NanNew<{{ cppClassName }}>({{= parsedName =}}); {%endif%} {%elsif cppClassName == 'External' %} -to = NanNew((void *){{{ parsedName }}}); +to = NanNew((void *){{= parsedName =}}); {%elsif cppClassName == 'Array' %} {%-- // FIXME this is not general purpose enough. --%} -Local tmpArray = NanNew({{{ parsedName }}}->{{ size }}); -for (unsigned int i = 0; i < {{{ parsedName }}}->{{ size }}; i++) { - tmpArray->Set(NanNew(i), NanNew({{{ parsedName }}}->{{ key }}[i])); +Local tmpArray = NanNew({{= parsedName =}}->{{ size }}); +for (unsigned int i = 0; i < {{= parsedName =}}->{{ size }}; i++) { + tmpArray->Set(NanNew(i), NanNew({{= parsedName =}}->{{ key }}[i])); } to = tmpArray; {%else%} {%if copy %} -if ({{{ parsedName }}} != NULL) { - {{{ parsedName }}} = ({{ cType|replace '**' '*' }} {%if isPointer %}*{%endif%}){{ copy }}({{{ parsedName }}}); +if ({{= parsedName =}} != NULL) { + {{= parsedName =}} = ({{ cType|replace '**' '*' }} {%if not isPointer %}*{%endif%}){{ copy }}({{= parsedName =}}); } {%endif%} -if ({{{ parsedName }}} != NULL) { - to = {{ cppClassName }}::New((void *){{{ parsedName }}}); +if ({{= parsedName =}} != NULL) { + to = {{ cppClassName }}::New((void *){{= parsedName =}}); } else { to = NanNull(); } diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index f8b31d965..cfaf18aa6 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -56,7 +56,7 @@ from_{{ arg.name }} if (result != GIT_OK) { {%each argsInfo as arg %} {%if arg.shouldAlloc %} - free(<%= arg.name %>); + free({{ arg.name }}); {%endif%} {%endeach%} From 70aefe5a8247cfb6344ebd23ab8ecd8f53994f4f Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 3 Oct 2014 10:39:19 -0700 Subject: [PATCH 25/34] Starting to put the filters for templates back in --- generate/filters/is_pointer.js | 3 +++ generate/index.js | 21 ++------------------- generate/partials/convert_to_v8.cc | 4 ++-- generate/partials/fields.cc | 4 ++-- 4 files changed, 9 insertions(+), 23 deletions(-) create mode 100644 generate/filters/is_pointer.js diff --git a/generate/filters/is_pointer.js b/generate/filters/is_pointer.js new file mode 100644 index 000000000..a5dbb053e --- /dev/null +++ b/generate/filters/is_pointer.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return /\s*\*\s*/.test(cType); +}; diff --git a/generate/index.js b/generate/index.js index 9cb1de44b..b5fcd3bda 100644 --- a/generate/index.js +++ b/generate/index.js @@ -33,6 +33,7 @@ var filters = { or: require("./filters/or"), and: require("./filters/and"), isV8Value: require("./filters/is_v8_value"), + isPointer: require("./filters/is_pointer"), unPointer: require("./filters/un_pointer"), defaultValue: require("./filters/default_value") }; @@ -57,7 +58,6 @@ Object.keys(partials).forEach(function(partial) { var enabled = idefs.filter(function(idef) { // Additionally provide a friendly name to the actual filename. idef.name = path.basename(idef.filename, ".h"); - idef.cTypeIsUndefined = typeof idef.cType == 'undefined'; // We need some custom data on each of the functions idef.functions.forEach(function(fn) { @@ -102,7 +102,6 @@ var enabled = idefs.filter(function(idef) { arg.cArg = cArg; arg.v8ValueClassName = cppToV8(arg.cppClassName); arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); - arg.isPointer = /\s*\*\s*/.test(arg.cType); arg.isDoublePointer = /\s*\*\*\s*/.test(arg.cType); arg.isV8Value = ~v8Values.indexOf(arg.cppClassName); @@ -114,7 +113,7 @@ var enabled = idefs.filter(function(idef) { fn.returns = []; // generate returns data - fn.argsInfo.forEach(function(arg) { + fn.args.forEach(function(arg) { if (!arg.isReturn) return; var _return = {}; @@ -135,21 +134,6 @@ var enabled = idefs.filter(function(idef) { if (!fn.returns.length && !fn.return.isErrorCode && fn.return.cType != "void") { - var _return = {}; - - _return = fn.return; - - _return.v8ValueClassName = cppToV8(_return.cppClassName); - _return.isCppClassStringOrArray = ~["String", "Array"].indexOf(_return.cppClassName); - _return.isPointer = /\s*\*\s*/.test(_return.cType); - _return.isDoublePointer = /\s*\*\*\s*/.test(_return.cType); - _return.isV8Value = ~v8Values.indexOf(_return.cppClassName); - _return.parsedName = 'result'; - _return.jsOrCppClassName = _return.jsClassName || _return.cppClassName; - _return.isCppClassIntType = ~["Uint32", "Int32"].indexOf(_return.cppClassName); - _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; - _return.jsNameOrName = _return.jsName | _return.name; - fn.returns.push(fn.return); } @@ -171,7 +155,6 @@ var enabled = idefs.filter(function(idef) { fieldInfo.parsedName = field.name || "result"; fieldInfo.isCppClassIntType = ~["Uin32", "Int32"].indexOf(field.cppClassName); fieldInfo.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; - fieldInfo.isV8Value = ~v8Values.indexOf(field.cppClassName); fn.fieldInfos.push(fieldInfo); }); diff --git a/generate/partials/convert_to_v8.cc b/generate/partials/convert_to_v8.cc index 7e527d218..ebe2b9dea 100644 --- a/generate/partials/convert_to_v8.cc +++ b/generate/partials/convert_to_v8.cc @@ -10,7 +10,7 @@ to = NanNew({{= parsedName =}}); {%if freeFunctionName %} {{ freeFunctionName }}({{= parsedName =}}); {%endif%} -{%elsif isV8Value %} +{%elsif cppClassName|isV8Value %} {%if isCppClassIntType %} to = NanNew<{{ cppClassName }}>(({{ parsedClassName }}){{= parsedName =}}); {%else%} @@ -30,7 +30,7 @@ to = tmpArray; {%else%} {%if copy %} if ({{= parsedName =}} != NULL) { - {{= parsedName =}} = ({{ cType|replace '**' '*' }} {%if not isPointer %}*{%endif%}){{ copy }}({{= parsedName =}}); + {{= parsedName =}} = ({{ cType|replace '**' '*' }} {%if not cType|isPointer %}*{%endif%}){{ copy }}({{= parsedName =}}); } {%endif%} if ({{= parsedName =}} != NULL) { diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc index 1ee5e9406..42243388b 100644 --- a/generate/partials/fields.cc +++ b/generate/partials/fields.cc @@ -5,8 +5,8 @@ NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { NanScope(); Handle to; - {{ field.cType }} {%if field.isV8Value %}*{%endif%}{{ field.name }} = - {%if not field.isV8Value %}&{%endif%}ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }}; + {{ field.cType }} {%if field.cppClassName|isV8Value %}*{%endif%}{{ field.name }} = + {%if not field.cppClassName|isV8Value %}&{%endif%}ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }}; {%partial convertToV8 field %} NanReturnValue(to); From f34ccc280da8678649a39538af3eeae998ca613b Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 3 Oct 2014 11:03:30 -0700 Subject: [PATCH 26/34] Added hasReturnType and isDoublePointer filter back in --- generate/filters/has_return_type.js | 7 +++++++ generate/filters/is_double_pointer.js | 3 +++ generate/filters/is_v8_value.js | 2 +- generate/index.js | 17 +++-------------- generate/partials/async_function.cc | 9 +++++---- generate/partials/convert_from_v8.cc | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 generate/filters/has_return_type.js create mode 100644 generate/filters/is_double_pointer.js diff --git a/generate/filters/has_return_type.js b/generate/filters/has_return_type.js new file mode 100644 index 000000000..2d21a0e66 --- /dev/null +++ b/generate/filters/has_return_type.js @@ -0,0 +1,7 @@ +module.exports = function(functionInfo) { + if (functionInfo.return) { + return functionInfo.return.cType != "void" || functionInfo.return.isErrorCode; + } + + return false; +}; diff --git a/generate/filters/is_double_pointer.js b/generate/filters/is_double_pointer.js new file mode 100644 index 000000000..9d1246ab4 --- /dev/null +++ b/generate/filters/is_double_pointer.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return /\s*\*\*\s*/.test(cType); +}; diff --git a/generate/filters/is_v8_value.js b/generate/filters/is_v8_value.js index f99a13f59..f773ff6a2 100644 --- a/generate/filters/is_v8_value.js +++ b/generate/filters/is_v8_value.js @@ -10,5 +10,5 @@ var v8 = [ ]; module.exports = function(cppClassName) { - return v8.indexOf(cppClassName) > -1 ? true : false; + return v8.indexOf(cppClassName) > -1; }; diff --git a/generate/index.js b/generate/index.js index b5fcd3bda..a75f10676 100644 --- a/generate/index.js +++ b/generate/index.js @@ -34,7 +34,9 @@ var filters = { and: require("./filters/and"), isV8Value: require("./filters/is_v8_value"), isPointer: require("./filters/is_pointer"), + isDoublePointer: require("./filters/is_double_pointer"), unPointer: require("./filters/un_pointer"), + hasReturnType: require("./filters/has_return_type"), defaultValue: require("./filters/default_value") }; @@ -68,17 +70,7 @@ var enabled = idefs.filter(function(idef) { fn.argsInfo = []; var cArg, - jsArg, - v8Values = [ - "Boolean", - "Number", - "String", - "Integer", - "Int32", - "Uint32", - "Date", - "Function" - ];; + jsArg; for(cArg = 0, jsArg = 0; cArg < fn.args.length; cArg++) { var arg = {}; @@ -102,8 +94,6 @@ var enabled = idefs.filter(function(idef) { arg.cArg = cArg; arg.v8ValueClassName = cppToV8(arg.cppClassName); arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); - arg.isDoublePointer = /\s*\*\*\s*/.test(arg.cType); - arg.isV8Value = ~v8Values.indexOf(arg.cppClassName); fn.argsInfo.push(arg); } @@ -142,7 +132,6 @@ var enabled = idefs.filter(function(idef) { } fn.hasReturns = fn.returns.length || fn.return.isErrorCode; - fn.hasReturnType = fn.return.cType != "void" || fn.return.isErrorCode; // generate fields data fn.fields = fn.fields || []; diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 10677385a..0c45fec80 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -45,14 +45,15 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { } void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { - {%if hasReturnType %} - {{ return.cType }} result = - {%endif%} + {%if .|hasReturnType %} + {{ return.cType }} result = {{ cFunctionName }}( + {%else%} {{ cFunctionName }}( + {%endif%} {%-- Insert Function Arguments --%} {%each argsInfo as arg %} {%-- turn the pointer into a ref --%} - {%if arg.isReturn %}{%if arg.isDoublePointer %}&{%endif%}{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} + {%if arg.isReturn %}{%if arg.cType|isDoublePointer %}&{%endif%}{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} {%endeach%} ); diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc index 58fc1eb9e..c425206d4 100644 --- a/generate/partials/convert_from_v8.cc +++ b/generate/partials/convert_from_v8.cc @@ -18,7 +18,7 @@ {%elsif cppClassName == 'Function' %} {%elsif cppClassName == 'Buffer' %} from_{{ name }} = Buffer::Data(args[{{ jsArg }}]->ToObject()); - {%elsif isV8Value %} + {%elsif cppClassName|isV8Value %} from_{{ name }} = ({{ cType }}) {{ additionalCast }} {{ cast }} args[{{ jsArg }}]->To{{ cppClassName }}()->Value(); {%else%} from_{{ name }} = ObjectWrap::Unwrap<{{ cppClassName }}>(args[{{ jsArg }}]->ToObject())->GetValue(); From 79fe10b1ed691a862201ce59dfc92789c8ecd42a Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 3 Oct 2014 12:37:19 -0700 Subject: [PATCH 27/34] Added more filters for combine templates back in --- generate/filters/args_info.js | 33 ++++++++++ generate/filters/convert_returns.js | 34 +++++++++++ generate/filters/fields_info.js | 17 ++++++ generate/filters/has_returns.js | 15 +++++ generate/filters/js_args_count.js | 18 ++++++ generate/filters/returns_count.js | 15 +++++ generate/index.js | 91 ++-------------------------- generate/partials/async_function.cc | 24 ++++---- generate/partials/doc.cc | 2 +- generate/partials/fields.cc | 2 +- generate/partials/guard_arguments.cc | 2 +- generate/partials/sync_function.cc | 24 ++++---- 12 files changed, 165 insertions(+), 112 deletions(-) create mode 100644 generate/filters/args_info.js create mode 100644 generate/filters/convert_returns.js create mode 100644 generate/filters/fields_info.js create mode 100644 generate/filters/has_returns.js create mode 100644 generate/filters/js_args_count.js create mode 100644 generate/filters/returns_count.js diff --git a/generate/filters/args_info.js b/generate/filters/args_info.js new file mode 100644 index 000000000..0f77e1e77 --- /dev/null +++ b/generate/filters/args_info.js @@ -0,0 +1,33 @@ +var cppToV8 = require("./cpp_to_v8"); + +module.exports = function(args) { + var result = [], + cArg, + jsArg; + + for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { + var arg = args[cArg]; + + if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { + arg.isJsArg = true; + arg.jsArg = jsArg; + + jsArg++; + } + + if (cArg >= args.length -1) { + arg.lastArg = true; + } + else { + arg.lastArg = false; + } + + arg.cArg = cArg; + arg.v8ValueClassName = cppToV8(arg.cppClassName); + arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); + + result.push(arg); + } + + return result; +}; diff --git a/generate/filters/convert_returns.js b/generate/filters/convert_returns.js new file mode 100644 index 000000000..2912405ad --- /dev/null +++ b/generate/filters/convert_returns.js @@ -0,0 +1,34 @@ +module.exports = function(fn) { + var result = []; + var args = fn.args || []; + + args.forEach(function (arg) { + if (!arg.isReturn) return; + + var _return = {}; + + _return.__proto__ = arg; + + _return.parsedName = result.length === 1 ? "baton->" + _return.name : _return.name; + _return.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(_return.cppClassName); + _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; + _return.jsNameOrName = _return.jsName | _return.name; + _return.jsOrCppClassName = _return.jsClassName || _return.cppClassName; + + result.push(_return); + }); + + if (!result.length + && fn.return + && !fn.return.isErrorCode + && fn.return.cType != "void") { + result.push(fn.return); + } + + if (result.length === 1) { + result[0].parsedName = result[0].name ? "baton->" + result[0].name : "result"; + } + + + return result; +}; diff --git a/generate/filters/fields_info.js b/generate/filters/fields_info.js new file mode 100644 index 000000000..27ed67973 --- /dev/null +++ b/generate/filters/fields_info.js @@ -0,0 +1,17 @@ +module.exports = function(fields) { + var result = []; + + fields.forEach(function (field){ + var fieldInfo = {}; + + fieldInfo.__proto__ = field; + + fieldInfo.parsedName = field.name || "result"; + fieldInfo.isCppClassIntType = ~["Uin32", "Int32"].indexOf(field.cppClassName); + fieldInfo.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; + + result.push(fieldInfo); + }); + + return result; +}; diff --git a/generate/filters/has_returns.js b/generate/filters/has_returns.js new file mode 100644 index 000000000..733bfe6a3 --- /dev/null +++ b/generate/filters/has_returns.js @@ -0,0 +1,15 @@ +module.exports = function(fn) { + var args = fn.args || []; + var result = args.some(function (arg) { + return arg.isReturn; + }); + + if (!result + && fn.return + && !fn.return.isErrorCode + && fn.return.cType != "void") { + result = true; + } + + return result || (fn.return && fn.return.isErrorCode); +}; diff --git a/generate/filters/js_args_count.js b/generate/filters/js_args_count.js new file mode 100644 index 000000000..5be437f41 --- /dev/null +++ b/generate/filters/js_args_count.js @@ -0,0 +1,18 @@ +module.exports = function(args) { + var cArg, + jsArg; + + if (!args) { + return 0; + } + + for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { + var arg = args[cArg]; + + if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { + jsArg++; + } + } + + return jsArg; +}; diff --git a/generate/filters/returns_count.js b/generate/filters/returns_count.js new file mode 100644 index 000000000..9ba92aec4 --- /dev/null +++ b/generate/filters/returns_count.js @@ -0,0 +1,15 @@ +module.exports = function(fn) { + var args = fn.args || []; + var result = args.reduce(function (currentValue, arg) { + return currentValue + (arg.isReturn ? 1 : 0); + }, 0); + + if (!result + && fn.return + && !fn.return.isErrorCode + && fn.return.cType != "void") { + result = 1; + } + + return result; +}; diff --git a/generate/index.js b/generate/index.js index a75f10676..9cf2157a5 100644 --- a/generate/index.js +++ b/generate/index.js @@ -2,7 +2,6 @@ const path = require("path"); const combyne = require("combyne"); const file = require("./util/file"); const idefs = require("./idefs"); -var cppToV8 = require("./filters/cpp_to_v8"); // Customize the delimiters so as to not process `{{{` or `}}}`. combyne.settings.delimiters = { @@ -32,12 +31,17 @@ var filters = { replace: require("./filters/replace"), or: require("./filters/or"), and: require("./filters/and"), + argsInfo: require("./filters/args_info"), + jsArgsCount: require("./filters/js_args_count"), isV8Value: require("./filters/is_v8_value"), isPointer: require("./filters/is_pointer"), isDoublePointer: require("./filters/is_double_pointer"), unPointer: require("./filters/un_pointer"), hasReturnType: require("./filters/has_return_type"), - defaultValue: require("./filters/default_value") + hasReturns: require("./filters/has_returns"), + returnsCount: require("./filters/returns_count"), + convertReturns: require("./filters/convert_returns"), + fieldsInfo: require("./filters/fields_info") }; // Convert Buffers to Combyne templates. @@ -64,89 +68,6 @@ var enabled = idefs.filter(function(idef) { // We need some custom data on each of the functions idef.functions.forEach(function(fn) { fn.cppClassName = idef.cppClassName; - - // generate argument info - fn.args = fn.args || []; - fn.argsInfo = []; - - var cArg, - jsArg; - - for(cArg = 0, jsArg = 0; cArg < fn.args.length; cArg++) { - var arg = {}; - - arg.__proto__ = fn.args[cArg]; - - if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { - arg.isJsArg = true; - arg.jsArg = jsArg; - - jsArg++; - } - - if (cArg >= fn.args.length -1) { - arg.lastArg = true; - } - else { - arg.lastArg = false; - } - - arg.cArg = cArg; - arg.v8ValueClassName = cppToV8(arg.cppClassName); - arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); - - fn.argsInfo.push(arg); - } - - fn.jsArgsCount = jsArg; - - fn.returns = []; - - // generate returns data - fn.args.forEach(function(arg) { - if (!arg.isReturn) return; - - var _return = {}; - - _return.__proto__ = arg; - - _return.parsedName = _return.name; - _return.jsOrCppClassName = _return.jsClassName || _return.cppClassName; - _return.isCppClassIntType = ~["Uint32", "Int32"].indexOf(_return.cppClassName); - _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; - _return.jsNameOrName = _return.jsName | _return.name; - - fn.returns.push(_return); - }); - - fn.return = fn.return || {}; - - if (!fn.returns.length - && !fn.return.isErrorCode - && fn.return.cType != "void") { - fn.returns.push(fn.return); - } - - if (fn.returns.length === 1) { - fn.returns[0].parsedName = fn.returns[0].name ? "baton->" + fn.returns[0].name : "result"; - } - - fn.hasReturns = fn.returns.length || fn.return.isErrorCode; - - // generate fields data - fn.fields = fn.fields || []; - fn.fieldInfos = []; - - fn.fields.forEach(function (field) { - var fieldInfo = {}; - fieldInfo.__proto__ = field; - - fieldInfo.parsedName = field.name || "result"; - fieldInfo.isCppClassIntType = ~["Uin32", "Int32"].indexOf(field.cppClassName); - fieldInfo.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; - - fn.fieldInfos.push(fieldInfo); - }); }); return !idef.ignore; diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 0c45fec80..071d91efe 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -5,14 +5,14 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { NanScope(); {%partial guardArguments .%} - if (args.Length() == {{ jsArgsCount }} || !args[{{ jsArgsCount }}]->IsFunction()) { + if (args.Length() == {{args|jsArgsCount}} || !args[{{args|jsArgsCount}}]->IsFunction()) { return NanThrowError("Callback is required and must be a Function."); } {{ cppFunctionName }}Baton* baton = new {{ cppFunctionName }}Baton; baton->error_code = GIT_OK; baton->error = NULL; - {%each argsInfo as arg %} + {%each args|argsInfo as arg %} {%if not arg.isReturn %} {%if arg.isSelf %} baton->{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue(); @@ -27,9 +27,9 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%endif%} {%endeach%} - NanCallback *callback = new NanCallback(Local::Cast(args[{{ jsArgsCount }}])); + NanCallback *callback = new NanCallback(Local::Cast(args[{{args|jsArgsCount}}])); {{ cppFunctionName }}Worker *worker = new {{ cppFunctionName }}Worker(baton, callback); - {%each argsInfo as arg %} + {%each args|argsInfo as arg %} {%if not arg.isReturn %} {%if arg.isSelf %} worker->SaveToPersistent("{{ arg.name }}", args.This()); @@ -51,9 +51,9 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { {{ cFunctionName }}( {%endif%} {%-- Insert Function Arguments --%} - {%each argsInfo as arg %} + {%each args|argsInfo as arg %} {%-- turn the pointer into a ref --%} - {%if arg.isReturn %}{%if arg.cType|isDoublePointer %}&{%endif%}{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} + {%if arg.isReturn|and arg.cType|isDoublePointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} {%endeach%} ); @@ -74,20 +74,20 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { TryCatch try_catch; if (baton->error_code == GIT_OK) { - {%if not returns.length %} + {%if not .|returnsCount %} Handle result = NanUndefined(); {%else%} Handle to; - {%if returns.length > 1 %} + {%if .|returnsCount > 1 %} Handle result = NanNew(); {%endif%} - {%each returns as _return %} + {%each .|convertReturns as _return %} {%partial convertToV8 _return %} - {%if returns.length > 1 %} + {%if .|returnsCount > 1 %} result->Set(NanNew("{{ _return.jsNameOrName }}"), to); {%endif%} {%endeach%} - {%if returns.length == 1 %} + {%if .|returnsCount == 1 %} Handle result = to; {%endif%} {%endif%} @@ -120,7 +120,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { node::FatalException(try_catch); } - {%each argsInfo as arg %} + {%each args|argsInfo as arg %} {%if arg.isCppClassStringOrArray %} {%if arg.freeFunctionName %} {{ arg.freeFunctionName }}(baton->{{ arg.name }}); diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index 0169e2bf0..e87aee23b 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -5,7 +5,7 @@ {%endif%} {%endif%} {%endeach%} -{%each returns as returnInfo %} +{%each .|convertReturns as returnInfo %} {%if isAsync %} * @param {{ returnInfo.jsOrCppClassName }} callback {%else%} diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc index 42243388b..c43467482 100644 --- a/generate/partials/fields.cc +++ b/generate/partials/fields.cc @@ -1,4 +1,4 @@ -{%each fieldInfos as field %} +{%each fields|fieldsInfo as field %} {%if not field.ignore %} NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { diff --git a/generate/partials/guard_arguments.cc b/generate/partials/guard_arguments.cc index 9927362a3..1b109c78f 100644 --- a/generate/partials/guard_arguments.cc +++ b/generate/partials/guard_arguments.cc @@ -1,4 +1,4 @@ -{%each argsInfo as arg%} +{%each args|argsInfo as arg%} {%if arg.isJsArg%} {%if not arg.isOptional%} if (args.Length() == {{arg.jsArg}} || !args[{{arg.jsArg}}]->Is{{arg.v8ValueClassName}}()) { diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index cfaf18aa6..1e1fe3806 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -5,7 +5,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { NanScope(); {%partial guardArguments .%} - {%each argsInfo as arg %} + {%each arg|argsInfo as arg %} {%if arg.isReturn %} {%if arg.shouldAlloc %} {{ arg.cType }}{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|unPointer }})); @@ -15,7 +15,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%endif%} {%endeach%} - {%each argsInfo as arg %} + {%each args|argsInfo as arg %} {%if not arg.isSelf %} {%if not arg.isReturn %} {%partial convertFromV8 arg %} @@ -23,9 +23,9 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%endif%} {%endeach%} -{%if hasReturns %} +{%if .|hasReturns %} {{ return.cType }} result = {%endif%}{{ cFunctionName }}( - {%each argsInfo as arg %} + {%each args|argsInfo as arg %} {%if arg.isReturn %} {%if not arg.shouldAlloc %} & @@ -42,7 +42,7 @@ from_{{ arg.name }} {%endeach%} ); -{%each argsInfo as arg %} +{%each args|argsInfo as arg %} {%if arg.isCppClassStringOrArray %} {%if arg.freeFunctionName %} {{ arg.freeFunctionName }}(from_{{ arg.name }}); @@ -54,8 +54,8 @@ from_{{ arg.name }} {%if return.isErrorCode %} if (result != GIT_OK) { - {%each argsInfo as arg %} - {%if arg.shouldAlloc %} + {%each args|argsInfo as arg %} + {%if arg.shouldAlloc %} free({{ arg.name }}); {%endif%} {%endeach%} @@ -68,20 +68,20 @@ from_{{ arg.name }} } {%endif%} -{%if not returns.length %} +{%if not .|returnsCount %} NanReturnUndefined(); {%else%} Handle to; - {%if returns.length > 1 %} + {%if .|returnsCount > 1 %} Handle toReturn = NanNew(); {%endif%} - {%each returns as _return %} + {%each .|convertReturns as _return %} {%partial convertToV8 _return %} - {%if returns.length > 1 %} + {%if .|returnsCount > 1 %} toReturn->Set(NanNew("{{ _return.jsNameOrName }}"), to); {%endif%} {%endeach%} - {%if returns.length == 1 %} + {%if .|returnsCount == 1 %} NanReturnValue(to); {%else%} NanReturnValue(toReturn); From cac31a5e070c6cd213151bd41b0f5e50fa69461e Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 3 Oct 2014 12:46:47 -0700 Subject: [PATCH 28/34] Some cleanup in templates --- generate/filters/args_info.js | 3 --- generate/filters/convert_returns.js | 34 ---------------------------- generate/filters/returns_info.js | 34 ++++++++++++++++++++++++++++ generate/index.js | 3 ++- generate/partials/async_function.cc | 2 +- generate/partials/convert_from_v8.cc | 2 +- generate/partials/doc.cc | 2 +- generate/partials/guard_arguments.cc | 2 +- generate/partials/sync_function.cc | 2 +- 9 files changed, 41 insertions(+), 43 deletions(-) delete mode 100644 generate/filters/convert_returns.js create mode 100644 generate/filters/returns_info.js diff --git a/generate/filters/args_info.js b/generate/filters/args_info.js index 0f77e1e77..8ccc77812 100644 --- a/generate/filters/args_info.js +++ b/generate/filters/args_info.js @@ -1,5 +1,3 @@ -var cppToV8 = require("./cpp_to_v8"); - module.exports = function(args) { var result = [], cArg, @@ -23,7 +21,6 @@ module.exports = function(args) { } arg.cArg = cArg; - arg.v8ValueClassName = cppToV8(arg.cppClassName); arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); result.push(arg); diff --git a/generate/filters/convert_returns.js b/generate/filters/convert_returns.js deleted file mode 100644 index 2912405ad..000000000 --- a/generate/filters/convert_returns.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = function(fn) { - var result = []; - var args = fn.args || []; - - args.forEach(function (arg) { - if (!arg.isReturn) return; - - var _return = {}; - - _return.__proto__ = arg; - - _return.parsedName = result.length === 1 ? "baton->" + _return.name : _return.name; - _return.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(_return.cppClassName); - _return.parsedClassName = (_return.cppClassName || '').toLowerCase() + "_t"; - _return.jsNameOrName = _return.jsName | _return.name; - _return.jsOrCppClassName = _return.jsClassName || _return.cppClassName; - - result.push(_return); - }); - - if (!result.length - && fn.return - && !fn.return.isErrorCode - && fn.return.cType != "void") { - result.push(fn.return); - } - - if (result.length === 1) { - result[0].parsedName = result[0].name ? "baton->" + result[0].name : "result"; - } - - - return result; -}; diff --git a/generate/filters/returns_info.js b/generate/filters/returns_info.js new file mode 100644 index 000000000..00ba5fc7a --- /dev/null +++ b/generate/filters/returns_info.js @@ -0,0 +1,34 @@ +module.exports = function(fn) { + var result = []; + var args = fn.args || []; + + args.forEach(function (arg) { + if (!arg.isReturn) return; + + var return_info = {}; + + return_info.__proto__ = arg; + + return_info.parsedName = result.length === 1 ? "baton->" + return_info.name : return_info.name; + return_info.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(return_info.cppClassName); + return_info.parsedClassName = (return_info.cppClassName || '').toLowerCase() + "_t"; + return_info.jsNameOrName = return_info.jsName | return_info.name; + return_info.jsOrCppClassName = return_info.jsClassName || return_info.cppClassName; + + result.push(return_info); + }); + + if (!result.length + && fn.return + && !fn.return.isErrorCode + && fn.return.cType != "void") { + result.push(fn.return); + } + + if (result.length === 1) { + result[0].parsedName = result[0].name ? "baton->" + result[0].name : "result"; + } + + + return result; +}; diff --git a/generate/index.js b/generate/index.js index 9cf2157a5..6d7927644 100644 --- a/generate/index.js +++ b/generate/index.js @@ -32,6 +32,7 @@ var filters = { or: require("./filters/or"), and: require("./filters/and"), argsInfo: require("./filters/args_info"), + cppToV8: require("./filters/cpp_to_v8"), jsArgsCount: require("./filters/js_args_count"), isV8Value: require("./filters/is_v8_value"), isPointer: require("./filters/is_pointer"), @@ -40,7 +41,7 @@ var filters = { hasReturnType: require("./filters/has_return_type"), hasReturns: require("./filters/has_returns"), returnsCount: require("./filters/returns_count"), - convertReturns: require("./filters/convert_returns"), + returnsInfo: require("./filters/returns_info"), fieldsInfo: require("./filters/fields_info") }; diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 071d91efe..19dbd815f 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -81,7 +81,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { {%if .|returnsCount > 1 %} Handle result = NanNew(); {%endif%} - {%each .|convertReturns as _return %} + {%each .|returnsInfo as _return %} {%partial convertToV8 _return %} {%if .|returnsCount > 1 %} result->Set(NanNew("{{ _return.jsNameOrName }}"), to); diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc index c425206d4..6a19fe5ab 100644 --- a/generate/partials/convert_from_v8.cc +++ b/generate/partials/convert_from_v8.cc @@ -1,7 +1,7 @@ {%if not isPayload %} {{ cType }} from_{{ name }}; {%if isOptional %} - if (args[{{ jsArg }}]->Is{{ v8ValueClassName }}()) { + if (args[{{ jsArg }}]->Is{{ cppClassName|cppToV8 }}()) { {%endif%} {%if cppClassName == 'String' %} String::Utf8Value {{ name }}(args[{{ jsArg }}]->ToString()); diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index e87aee23b..d30eae84d 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -5,7 +5,7 @@ {%endif%} {%endif%} {%endeach%} -{%each .|convertReturns as returnInfo %} +{%each .|returnsInfo as returnInfo %} {%if isAsync %} * @param {{ returnInfo.jsOrCppClassName }} callback {%else%} diff --git a/generate/partials/guard_arguments.cc b/generate/partials/guard_arguments.cc index 1b109c78f..b48e561fb 100644 --- a/generate/partials/guard_arguments.cc +++ b/generate/partials/guard_arguments.cc @@ -1,7 +1,7 @@ {%each args|argsInfo as arg%} {%if arg.isJsArg%} {%if not arg.isOptional%} - if (args.Length() == {{arg.jsArg}} || !args[{{arg.jsArg}}]->Is{{arg.v8ValueClassName}}()) { + if (args.Length() == {{arg.jsArg}} || !args[{{arg.jsArg}}]->Is{{arg.cppClassName|cppToV8}}()) { return NanThrowError("{{arg.jsClassName}} {{arg.name}} is required."); } {%endif%} diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index 1e1fe3806..34ea710cb 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -75,7 +75,7 @@ from_{{ arg.name }} {%if .|returnsCount > 1 %} Handle toReturn = NanNew(); {%endif%} - {%each .|convertReturns as _return %} + {%each .|returnsInfo as _return %} {%partial convertToV8 _return %} {%if .|returnsCount > 1 %} toReturn->Set(NanNew("{{ _return.jsNameOrName }}"), to); From 89a94ca48b8636a7406179b8ab1abe1749cd75fd Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 3 Oct 2014 15:56:25 -0700 Subject: [PATCH 29/34] Fixed some more issues with the template conversion --- generate/filters/args_info.js | 2 +- generate/filters/fields_info.js | 2 +- generate/filters/returns_info.js | 16 +++++++++++----- generate/index.js | 1 + generate/partials/fields.cc | 2 +- generate/partials/sync_function.cc | 12 +++++------- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/generate/filters/args_info.js b/generate/filters/args_info.js index 8ccc77812..b2fb1aa5b 100644 --- a/generate/filters/args_info.js +++ b/generate/filters/args_info.js @@ -13,7 +13,7 @@ module.exports = function(args) { jsArg++; } - if (cArg >= args.length -1) { + if (cArg === args.length -1) { arg.lastArg = true; } else { diff --git a/generate/filters/fields_info.js b/generate/filters/fields_info.js index 27ed67973..8ec8a930b 100644 --- a/generate/filters/fields_info.js +++ b/generate/filters/fields_info.js @@ -7,7 +7,7 @@ module.exports = function(fields) { fieldInfo.__proto__ = field; fieldInfo.parsedName = field.name || "result"; - fieldInfo.isCppClassIntType = ~["Uin32", "Int32"].indexOf(field.cppClassName); + fieldInfo.isCppClassIntType = ~["Uint32", "Int32"].indexOf(field.cppClassName); fieldInfo.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; result.push(fieldInfo); diff --git a/generate/filters/returns_info.js b/generate/filters/returns_info.js index 00ba5fc7a..20693ec6f 100644 --- a/generate/filters/returns_info.js +++ b/generate/filters/returns_info.js @@ -1,4 +1,4 @@ -module.exports = function(fn) { +module.exports = function(fn, argReturnsOnly) { var result = []; var args = fn.args || []; @@ -19,14 +19,20 @@ module.exports = function(fn) { }); if (!result.length + && !argReturnsOnly && fn.return && !fn.return.isErrorCode && fn.return.cType != "void") { - result.push(fn.return); - } + var return_info = {}; + + return_info.__proto__ = fn.return; + return_info.parsedName = return_info.name ? "baton->" + return_info.name : "result"; + return_info.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(return_info.cppClassName); + return_info.parsedClassName = (return_info.cppClassName || '').toLowerCase() + "_t"; + return_info.jsNameOrName = return_info.jsName | return_info.name; + return_info.jsOrCppClassName = return_info.jsClassName || return_info.cppClassName; - if (result.length === 1) { - result[0].parsedName = result[0].name ? "baton->" + result[0].name : "result"; + result.push(return_info); } diff --git a/generate/index.js b/generate/index.js index 6d7927644..3ab3b136f 100644 --- a/generate/index.js +++ b/generate/index.js @@ -31,6 +31,7 @@ var filters = { replace: require("./filters/replace"), or: require("./filters/or"), and: require("./filters/and"), + defaultValue: require("./filters/default_value"), argsInfo: require("./filters/args_info"), cppToV8: require("./filters/cpp_to_v8"), jsArgsCount: require("./filters/js_args_count"), diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc index c43467482..45e17503c 100644 --- a/generate/partials/fields.cc +++ b/generate/partials/fields.cc @@ -5,7 +5,7 @@ NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { NanScope(); Handle to; - {{ field.cType }} {%if field.cppClassName|isV8Value %}*{%endif%}{{ field.name }} = + {{ field.cType }} {%if not field.cppClassName|isV8Value %}*{%endif%}{{ field.name }} = {%if not field.cppClassName|isV8Value %}&{%endif%}ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }}; {%partial convertToV8 field %} diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index 34ea710cb..08e6e17b4 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -5,13 +5,11 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { NanScope(); {%partial guardArguments .%} - {%each arg|argsInfo as arg %} - {%if arg.isReturn %} - {%if arg.shouldAlloc %} - {{ arg.cType }}{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|unPointer }})); - {%else%} - {{ arg.cType|unPointer }} {{ arg.name }} = {{ arg.cType|unPointer|defaultValue }}; - {%endif%} + {%each .|returnsInfo 'true' as _return %} + {%if _return.shouldAlloc %} + {{ _return.cType }}{{ _return.name }} = ({{ _return.cType }})malloc(sizeof({{ _return.cType|unPointer }})); + {%else%} + {{ _return.cType|unPointer }} {{ _return.name }} = {{ _return.cType|unPointer|defaultValue }}; {%endif%} {%endeach%} From 8f16afa72d2ce1abbf9d92d9254aa03c7ad9f584 Mon Sep 17 00:00:00 2001 From: John Haley Date: Fri, 3 Oct 2014 17:03:22 -0700 Subject: [PATCH 30/34] Combyne templates are good --- generate/filters/returns_info.js | 6 +++--- generate/partials/async_function.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generate/filters/returns_info.js b/generate/filters/returns_info.js index 20693ec6f..7279d5ff1 100644 --- a/generate/filters/returns_info.js +++ b/generate/filters/returns_info.js @@ -1,4 +1,4 @@ -module.exports = function(fn, argReturnsOnly) { +module.exports = function(fn, argReturnsOnly, isAsync) { var result = []; var args = fn.args || []; @@ -9,7 +9,7 @@ module.exports = function(fn, argReturnsOnly) { return_info.__proto__ = arg; - return_info.parsedName = result.length === 1 ? "baton->" + return_info.name : return_info.name; + return_info.parsedName = isAsync ? "baton->" + return_info.name : return_info.name; return_info.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(return_info.cppClassName); return_info.parsedClassName = (return_info.cppClassName || '').toLowerCase() + "_t"; return_info.jsNameOrName = return_info.jsName | return_info.name; @@ -26,7 +26,7 @@ module.exports = function(fn, argReturnsOnly) { var return_info = {}; return_info.__proto__ = fn.return; - return_info.parsedName = return_info.name ? "baton->" + return_info.name : "result"; + return_info.parsedName = return_info.name && isAsync ? "baton->" + return_info.name : "result"; return_info.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(return_info.cppClassName); return_info.parsedClassName = (return_info.cppClassName || '').toLowerCase() + "_t"; return_info.jsNameOrName = return_info.jsName | return_info.name; diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 19dbd815f..3b0d4dee0 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -81,7 +81,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { {%if .|returnsCount > 1 %} Handle result = NanNew(); {%endif%} - {%each .|returnsInfo as _return %} + {%each .|returnsInfo 0 1 as _return %} {%partial convertToV8 _return %} {%if .|returnsCount > 1 %} result->Set(NanNew("{{ _return.jsNameOrName }}"), to); From 686504071ee847a908b3e12368fb1137b9717646 Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Fri, 3 Oct 2014 21:12:20 -0400 Subject: [PATCH 31/34] Moved comments into partial, fixed alignment --- generate/partials/async_function.cc | 2 -- generate/partials/doc.cc | 11 ++++++----- generate/partials/sync_function.cc | 2 -- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index 3b0d4dee0..f9dd0c716 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -1,6 +1,4 @@ -/** {%partial doc .%} - */ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { NanScope(); {%partial guardArguments .%} diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc index d30eae84d..b3bbb5d46 100644 --- a/generate/partials/doc.cc +++ b/generate/partials/doc.cc @@ -1,14 +1,15 @@ +/** {%each args as arg %} {%if not arg.isReturn %} {%if not arg.isSelf %} - * @param {{ arg.jsClassName }} {{ arg.name }} +* @param {{ arg.jsClassName }} {{ arg.name }} {%endif%} {%endif%} -{%endeach%} -{%each .|returnsInfo as returnInfo %} +{%endeach%}{%each .|returnsInfo as returnInfo %} {%if isAsync %} - * @param {{ returnInfo.jsOrCppClassName }} callback + * @param {{ returnInfo.jsOrCppClassName }} callback {%else%} - * @return {{ returnInfo.jsOrCppClassName }} {%if returnInfo.name %}{{ returnInfo.name }}{%else%}result{%endif%} + * @return {{ returnInfo.jsOrCppClassName }} {%if returnInfo.name %}{{ returnInfo.name }}{%else%}result{%endif%} {%endif%} {%endeach%} +*/ diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index 08e6e17b4..6a3396541 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -1,6 +1,4 @@ -/** {%partial doc .%} - */ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { NanScope(); {%partial guardArguments .%} From db670ba051c47e48e7900ef8b66d6649e9212d61 Mon Sep 17 00:00:00 2001 From: John Haley Date: Mon, 6 Oct 2014 11:55:05 -0700 Subject: [PATCH 32/34] Generated templates are looking better --- generate/partials/async_function.cc | 1 + generate/partials/sync_function.cc | 4 +--- generate/templates/class.cc | 4 +++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc index f9dd0c716..7b201a44b 100644 --- a/generate/partials/async_function.cc +++ b/generate/partials/async_function.cc @@ -52,6 +52,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { {%each args|argsInfo as arg %} {%-- turn the pointer into a ref --%} {%if arg.isReturn|and arg.cType|isDoublePointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} + {%endeach%} ); diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc index 6a3396541..a22b45d45 100644 --- a/generate/partials/sync_function.cc +++ b/generate/partials/sync_function.cc @@ -23,9 +23,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {{ return.cType }} result = {%endif%}{{ cFunctionName }}( {%each args|argsInfo as arg %} {%if arg.isReturn %} - {%if not arg.shouldAlloc %} - & - {%endif%} + {%if not arg.shouldAlloc %}&{%endif%} {%endif%} {%if arg.isSelf %} ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue() diff --git a/generate/templates/class.cc b/generate/templates/class.cc index 2456ae3ef..cf46d25b0 100644 --- a/generate/templates/class.cc +++ b/generate/templates/class.cc @@ -22,7 +22,9 @@ using namespace node; } {{ cppClassName }}::~{{ cppClassName }}() { - {%if freeFunctionName%}{{ freeFunctionName }}(this->raw);{%endif%} + {%if freeFunctionName%} + {{ freeFunctionName }}(this->raw); + {%endif%} } void {{ cppClassName }}::Initialize(Handle target) { From 9a29299a667471dd72bfda2de0879609313696ff Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Mon, 6 Oct 2014 21:14:37 -0400 Subject: [PATCH 33/34] Updated all NPM dependencies --- package.json | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index e8a9673d7..c751c2cc2 100644 --- a/package.json +++ b/package.json @@ -40,27 +40,27 @@ "node-pre-gyp" ], "dependencies": { - "fs-extra": "^0.12.0", - "nan": "^1.3.0", - "node-gyp": "^1.0.2", - "node-pre-gyp": "^0.5.27", - "q": "^1.0.1", - "ejs": "^1.0.0", - "combyne": "^0.5.5", - "request": "^2.44.0", - "rimraf": "^2.2.8", - "tar": "^1.0.1", - "which": "^1.0.5", - "promise": "^6.0.0", - "promisify-node": "^0.1.2" + "fs-extra": "~0.12.0", + "nan": "~1.3.0", + "node-gyp": "~1.0.2", + "node-pre-gyp": "~0.5.27", + "q": "~1.0.1", + "ejs": "~1.0.0", + "combyne": "~0.6.0", + "request": "~2.45.0", + "rimraf": "~2.2.8", + "tar": "~1.0.1", + "which": "~1.0.5", + "promise": "~6.0.0", + "promisify-node": "~0.1.2" }, "devDependencies": { - "async": "^0.9.0", - "aws-sdk": "^2.0.17", - "istanbul": "^0.3.2", - "jshint": "^2.5.6", - "mocha": "^1.21.4", - "nodeunit": "^0.9.0" + "async": "~0.9.0", + "aws-sdk": "~2.0.18", + "istanbul": "~0.3.2", + "jshint": "~2.5.6", + "mocha": "~1.21.4", + "nodeunit": "~0.9.0" }, "binary": { "module_name": "nodegit", @@ -76,4 +76,4 @@ "install": "npm run generate && node install", "rebuild": "npm run generate && node-gyp configure build" } -} +} \ No newline at end of file From bc0e87e038e73c349f1b6a5f9287a71a8c8ae044 Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Mon, 6 Oct 2014 21:27:41 -0400 Subject: [PATCH 34/34] Updated the README examples to use promises --- README.md | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index c2e03d931..6daa45d42 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,8 @@ git clone git://github.com/tbranyen/nodegit.git # Enter the repository. cd nodegit -# Install the template engine, run the code generation script, and install. -npm install ejs && npm run codegen && npm install +# Installs the template engine, run the code generation script, and build. +npm install ``` If you encounter errors, you most likely have not configured the dependencies @@ -93,35 +93,19 @@ npm install nodegit --msvs_version=2013 ### Cloning a repository and reading a file: ### ``` javascript -var clone = require("nodegit").Repo.clone; +var clone = require("nodegit").Repository.clone; // Clone a given repository into a specific folder. -clone("https://github.com/nodegit/nodegit", "tmp", null, function(err, repo) { - if (err) { - throw err; - } - +clone("https://github.com/nodegit/nodegit", "tmp", null).then(function(repo) { // Use a known commit sha from this repository. var sha = "59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5"; // Look up this known commit. - repo.getCommit(sha, function(err, commit) { - if (err) { - throw err; - } - + repo.getCommit(sha).then(function(commit) { // Look up a specific file within that commit. - commit.getEntry("README.md", function(err, entry) { - if (err) { - throw err; - } - + commit.getEntry("README.md").then(function(entry) { // Get the blob contents from the file. - entry.getBlob(function(err, blob) { - if (err) { - throw err; - } - + entry.getBlob().then(function(blob) { // Show the name, sha, and filesize in byes. console.log(entry.name() + entry.sha() + blob.size() + "b"); @@ -139,20 +123,12 @@ clone("https://github.com/nodegit/nodegit", "tmp", null, function(err, repo) { ### Emulating git log: ### ``` javascript -var open = require("nodegit").Repo.open; +var open = require("nodegit").Repository.open; // Open the repository directory. -open("tmp", function(err, repo) { - if (err) { - throw err; - } - +open("tmp").then(function(repo) { // Open the master branch. - repo.getMaster(function(err, branch) { - if (err) { - throw err; - } - + repo.getMaster().then(function(branch) { // Create a new history event emitter. var history = branch.history();