From df2c3f3509ebaad7c627c815746d5a2fdcee343a Mon Sep 17 00:00:00 2001 From: Tyler Ang-Wanek Date: Fri, 24 May 2019 15:10:29 -0700 Subject: [PATCH] Root functions should keep their function prototypes correctly Without treating the root of a nodegit collection as a function template when it is a function itself, when we do the importextension / fix the prototype dance, we were blowing away call, bind, and apply, as well as anything else on the prototype --- generate/input/descriptor.json | 1 + generate/scripts/generateNativeCode.js | 2 ++ .../filters/get_cpp_function_for_root_proto.js | 12 ++++++++++++ .../filters/has_function_on_root_proto.js | 7 +++++++ generate/templates/templates/class_content.cc | 16 ++++++++++++++-- 5 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 generate/templates/filters/get_cpp_function_for_root_proto.js create mode 100644 generate/templates/filters/has_function_on_root_proto.js diff --git a/generate/input/descriptor.json b/generate/input/descriptor.json index e846c62e6..7db3b4c05 100644 --- a/generate/input/descriptor.json +++ b/generate/input/descriptor.json @@ -3408,6 +3408,7 @@ ], "functions": { "git_reset": { + "isCollectionRoot": true, "args": { "checkout_opts": { "isOptional": true diff --git a/generate/scripts/generateNativeCode.js b/generate/scripts/generateNativeCode.js index 8ba821903..44f0501a9 100644 --- a/generate/scripts/generateNativeCode.js +++ b/generate/scripts/generateNativeCode.js @@ -57,6 +57,8 @@ module.exports = function generateNativeCode() { cppToV8: require("../templates/filters/cpp_to_v8"), defaultValue: require("../templates/filters/default_value"), fieldsInfo: require("../templates/filters/fields_info"), + getCPPFunctionForRootProto: require("../templates/filters/get_cpp_function_for_root_proto"), + hasFunctionOnRootProto: require("../templates/filters/has_function_on_root_proto"), hasReturnType: require("../templates/filters/has_return_type"), hasReturnValue: require("../templates/filters/has_return_value"), isArrayType: require("../templates/filters/is_array_type"), diff --git a/generate/templates/filters/get_cpp_function_for_root_proto.js b/generate/templates/filters/get_cpp_function_for_root_proto.js new file mode 100644 index 000000000..6571af880 --- /dev/null +++ b/generate/templates/filters/get_cpp_function_for_root_proto.js @@ -0,0 +1,12 @@ +module.exports = function(functions) { + if (!functions || functions.length === 0) { + throw new Error("Should not be able to get function from empty function list"); + } + + const fun = functions.find(function(f) { return f.useAsOnRootProto; }); + if (!fun) { + throw new Error("There is no function on the root prototype for this collection"); + } + + return fun.cppFunctionName; +}; diff --git a/generate/templates/filters/has_function_on_root_proto.js b/generate/templates/filters/has_function_on_root_proto.js new file mode 100644 index 000000000..626ce0ff6 --- /dev/null +++ b/generate/templates/filters/has_function_on_root_proto.js @@ -0,0 +1,7 @@ +module.exports = function(functions) { + if (!functions || functions.length === 0) { + return false; + } + + return functions.some(function(f) { return f.useAsOnRootProto; }); +}; diff --git a/generate/templates/templates/class_content.cc b/generate/templates/templates/class_content.cc index 48e67b0eb..dbac5e097 100644 --- a/generate/templates/templates/class_content.cc +++ b/generate/templates/templates/class_content.cc @@ -79,7 +79,11 @@ using namespace node; void {{ cppClassName }}::InitializeComponent(v8::Local target) { Nan::HandleScope scope; - v8::Local object = Nan::New(); + {% if functions|hasFunctionOnRootProto %} + v8::Local object = Nan::New({{ functions|getCPPFunctionForRootProto }}); + {% else %} + v8::Local object = Nan::New(); + {% endif %} {% each functions as function %} {% if not function.ignore %} @@ -87,7 +91,15 @@ using namespace node; {% endif %} {% endeach %} - Nan::Set(target, Nan::New("{{ jsClassName }}").ToLocalChecked(), object); + Nan::Set( + target, + Nan::New("{{ jsClassName }}").ToLocalChecked(), + {% if functions|hasFunctionOnRootProto %} + Nan::GetFunction(object).ToLocalChecked() + {% else %} + object + {% endif %} + ); } {% endif %}