Commit 4e34797a authored by Mohseen Mukaddam's avatar Mohseen Mukaddam

Adding filters to generator template

AsyncBatonWithNoResults

wip 2
parent 239c5ad1
......@@ -311,6 +311,102 @@
"error": -1
}
},
"git_filter_apply_fn": {
"args": [
{
"name": "self",
"cType": "git_filter *"
},
{
"name": "payload",
"cType": "void **"
},
{
"name": "to",
"cType": "git_buf *"
},
{
"name": "from",
"cType": "const git_buf *"
},
{
"name": "src",
"cType": "const git_filter_source *"
}
],
"return": {
"type": "int",
"noResults": -30,
"success": 0,
"error": -1
}
},
"git_filter_check_fn": {
"args": [
{
"name": "self",
"cType": "git_filter *"
},
{
"name": "payload",
"cType": "void **"
},
{
"name": "src",
"cType": "const git_filter_source *"
},
{
"name": "attr_values",
"cType": "const char **"
}
],
"return": {
"type": "int",
"noResults": -30,
"success": 0,
"error": -1
}
},
"git_filter_cleanup_fn": {
"args": [
{
"name": "self",
"cType": "git_filter *"
},
{
"name": "payload",
"cType": "void *"
}
],
"return": {
"type": "void"
}
},
"git_filter_init_fn": {
"args": [
{
"name": "self",
"cType": "git_filter *"
}
],
"return": {
"type": "int",
"noResults": 0,
"success": 0,
"error": -1
}
},
"git_filter_shutdown_fn": {
"args": [
{
"name": "self",
"cType": "git_filter *"
}
],
"return": {
"type": "void"
}
},
"git_index_matched_path_cb": {
"args": [
{
......
......@@ -879,6 +879,7 @@
}
},
"filter": {
"hasConstructor": true,
"functions": {
"git_filter_list_apply_to_blob": {
"ignore": true
......@@ -920,30 +921,21 @@
"ignore": true
}
},
"cDependencies": [
"git2/sys/filter.h"
],
"fields": {
"initialize": {
"ignore": true
},
"shutdown": {
"ignore": true
},
"check": {
"ignore": true
},
"apply": {
"ignore": true
},
"cleanup": {
"stream": {
"ignore": true
}
},
}
},
"filter_source": {
"ignore": false,
"cDependencies": [
"git2/sys/filter.h"
]
},
"filter_source": {
"ignore": true
},
"graph": {
"functions": {
"git_graph_ahead_behind": {
......
......@@ -273,6 +273,17 @@
"git_annotated_commit_lookup"
]
],
[
"filter_source",
[
"git_filter_source_repo",
"git_filter_source_path",
"git_filter_source_filemode",
"git_filter_source_id",
"git_filter_source_mode",
"git_filter_source_flags"
]
],
[
"odb_object",
[
......@@ -422,33 +433,27 @@
},
{
"type": "git_filter_init_fn",
"name": "initialize",
"ignore": true
"name": "initialize"
},
{
"type": "git_filter_shutdown_fn",
"name": "shutdown",
"ignore": true
"name": "shutdown"
},
{
"type": "git_filter_check_fn",
"name": "check",
"ignore": true
"name": "check"
},
{
"type": "git_filter_apply_fn",
"name": "apply",
"ignore": true
"name": "apply"
},
{
"type": "git_filter_stream_fn",
"name": "stream",
"ignore": true
"name": "stream"
},
{
"type": "git_filter_cleanup_fn",
"name": "cleanup",
"ignore": true
"name": "cleanup"
}
]
}
......@@ -765,14 +770,26 @@
"git_annotated_commit_lookup"
]
},
"odb": {
"filter": {
"functions": [
"git_odb_object_data",
"git_odb_object_dup",
"git_odb_object_free",
"git_odb_object_id",
"git_odb_object_size",
"git_odb_object_type"
"git_filter_list_apply_to_blob",
"git_filter_list_apply_to_data",
"git_filter_list_apply_to_file",
"git_filter_list_contains",
"git_filter_list_free",
"git_filter_list_length",
"git_filter_list_load",
"git_filter_list_new",
"git_filter_list_push",
"git_filter_list_stream_blob",
"git_filter_list_stream_data",
"git_filter_list_stream_file",
"git_filter_source_filemode",
"git_filter_source_flags",
"git_filter_source_id",
"git_filter_source_mode",
"git_filter_source_path",
"git_filter_source_repo"
]
},
"merge": {
......@@ -784,6 +801,16 @@
"git_merge_head_id"
]
},
"odb": {
"functions": [
"git_odb_object_data",
"git_odb_object_dup",
"git_odb_object_free",
"git_odb_object_id",
"git_odb_object_size",
"git_odb_object_type"
]
},
"reflog": {
"functions": [
"git_reflog_entry_committer",
......
......@@ -61,6 +61,7 @@ module.exports = function generateJson() {
// Split each type from the array into classes/structs and enums
// each entry is of type ['name', {definingobject}]
libgit2.types.forEach(function(current) {
console.log(current[1]);
current[1].typeName = current[0];
// just log these out to a file for fun
......@@ -106,6 +107,7 @@ module.exports = function generateJson() {
}, {}).valueOf();
// decorate the definitions with required data to build the C++ files
//TODO: add self ref tag here
types.forEach(function(typeDef) {
var typeName = typeDef.typeName;
typeDef.cType = typeName;
......@@ -169,9 +171,18 @@ module.exports = function generateJson() {
}
};
var addSelfReferentialField = function(prop){
if (helpers.isSelfReferential(prop.type)) {
prop.isSelfReferential = true;
def.isExtendedStruct = true;
}
};
def.fields.forEach(addDependencies);
def.fields.forEach(addSelfReferentialField);
def.functions.forEach(addDependencies);
Object.keys(dependencies).forEach(function (dependencyFilename) {
def.dependencies.push("../include/" + dependencyFilename + ".h");
});
......@@ -183,7 +194,6 @@ module.exports = function generateJson() {
fn.cppClassName = def.cppClassName;
});
});
// Process enums
_(enums).forEach(function(enumerable) {
output.some(function(obj) {
......
var callbackTypePattern = /\s*_cb/;
var callbackTypePattern = /\s*_(cb|fn)/,
selfReferentialTypePattern = /\s*_fn/;
var utils = require("./utils");
var _ = require("lodash");
......@@ -10,6 +11,9 @@ var callbackDefs = require("../input/callbacks.json");
var descriptor = require("../input/descriptor.json");
var libgit2 = require("../input/libgit2-docs.json");
let funcs = Object.keys(libgit2.functions);
console.log(funcs.filter(item => item.includes('filter')));
var cTypes = libgit2.groups.map(function(group) { return group[0];});
var cTypeMappings = {
......@@ -93,6 +97,10 @@ var Helpers = {
&& ~cbField.name.indexOf(payloadName.replace("_payload", ""));
},
isSelfReferential: function(cType){
return selfReferentialTypePattern.test(cType);
},
getLibgitType: function(normalizedType, types) {
var libgitType;
......
......@@ -60,4 +60,40 @@ struct AsyncBatonWithResult : public AsyncBaton {
}
};
struct AsyncBatonWithNoResult : public AsyncBaton {
/* ResultT result;
ResultT defaultResult;*/ // result returned if the callback doesn't return anything valid
void (*onCompletion)(AsyncBaton *);
void Done() {
if (onCompletion) {
onCompletion(this);
} else {
// signal completion
uv_sem_post(&semaphore);
}
}
void ExecuteAsync(ThreadPool::Callback asyncCallback, void (*onCompletion)(AsyncBaton *) = NULL) {
this->onCompletion = onCompletion;
if (!onCompletion) {
uv_sem_init(&semaphore, 0);
}
{
LockMaster::TemporaryUnlock temporaryUnlock;
libgit2ThreadPool.ExecuteReverseCallback(asyncCallback, this);
if (!onCompletion) {
// wait for completion
uv_sem_wait(&semaphore);
uv_sem_destroy(&semaphore);
}
}
return;
}
};
#endif
......@@ -109,11 +109,20 @@
{% if field.isCallbackFunction %}
{{ cppClassName }}* {{ cppClassName }}::{{ field.name }}_getInstanceFromBaton({{ field.name|titleCase }}Baton* baton) {
return static_cast<{{ cppClassName }}*>(baton->{% each field.args|argsInfo as arg %}
{% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %}
{% endeach %});
{% if isExtendedStruct %}
return static_cast<{{ cppClassName }}*>((({{cType}}_extended *)baton->self)->payload);
{% else %}
return static_cast<{{ cppClassName }}*>(baton->
{% each field.args|argsInfo as arg %}
{% if arg.payload == true %}
{{arg.name}}
{% elsif arg.lastArg %}
{{arg.name}}
{% endif %}
{% endeach %});
{% endif %}
}
{{ field.return.type }} {{ cppClassName }}::{{ field.name }}_cppCallback (
{% each field.args|argsInfo as arg %}
{{ arg.cType }} {{ arg.name}}{% if not arg.lastArg %},{% endif %}
......@@ -127,21 +136,34 @@
{% endeach %}
{{ cppClassName }}* instance = {{ field.name }}_getInstanceFromBaton(baton);
{{ field.return.type }} result;
if (instance->{{ field.name }}.WillBeThrottled()) {
result = baton->defaultResult;
delete baton;
} else if (instance->{{ field.name }}.ShouldWaitForResult()) {
result = baton->ExecuteAsync({{ field.name }}_async);
delete baton;
} else {
result = baton->defaultResult;
baton->ExecuteAsync({{ field.name }}_async, deleteBaton);
}
return result;
{% if field.return.type == "void" %}
if (instance->{{ field.name }}.WillBeThrottled()) {
delete baton;
} else if (instance->{{ field.name }}.ShouldWaitForResult()) {
baton->ExecuteAsync({{ field.name }}_async);
delete baton;
} else {
baton->ExecuteAsync({{ field.name }}_async, deleteBaton);
}
return;
{% else %}
{{ field.return.type }} result;
if (instance->{{ field.name }}.WillBeThrottled()) {
result = baton->defaultResult;
delete baton;
} else if (instance->{{ field.name }}.ShouldWaitForResult()) {
result = baton->ExecuteAsync({{ field.name }}_async);
delete baton;
} else {
result = baton->defaultResult;
baton->ExecuteAsync({{ field.name }}_async, deleteBaton);
}
return result;
{% endif %}
}
void {{ cppClassName }}::{{ field.name }}_async(void *untypedBaton) {
Nan::HandleScope scope;
......@@ -150,11 +172,12 @@
{{ cppClassName }}* instance = {{ field.name }}_getInstanceFromBaton(baton);
if (instance->{{ field.name }}.GetCallback()->IsEmpty()) {
{% if field.return.type == "int" %}
{% if field.return.type == "void" %}
baton->Done();
{% else %}
baton->result = baton->defaultResult; // no results acquired
baton->Done();
{% endif %}
baton->Done();
return;
}
......@@ -173,8 +196,12 @@
v8::Local<Value> argv[{{ field.args|jsArgsCount }}] = {
{% each field.args|argsInfo as arg %}
{% if arg.name == "payload" %}
{%-- payload is always the last arg --%}
Nan::New(instance->{{ fields|payloadFor field.name }})
{% if isExtendedStruct %}
Nan::New((({{cType}}_extended *)instance)->payload),
{% else %}
{%-- payload is always the last arg --%}
Nan::New(instance->{{ fields|payloadFor field.name }}),
{% endif %}
{% elsif arg.isJsArg %}
{% if arg.isEnum %}
Nan::New((int)baton->{{ arg.name }}),
......@@ -198,40 +225,10 @@
if(PromiseCompletion::ForwardIfPromise(result, baton, {{ cppClassName }}::{{ field.name }}_promiseCompleted)) {
return;
}
{% each field|returnsInfo false true as _return %}
if (result.IsEmpty() || result->IsNativeError()) {
baton->result = {{ field.return.error }};
}
else if (!result->IsNull() && !result->IsUndefined()) {
{% if _return.isOutParam %}
{{ _return.cppClassName }}* wrapper = Nan::ObjectWrap::Unwrap<{{ _return.cppClassName }}>(result->ToObject());
wrapper->selfFreeing = false;
*baton->{{ _return.name }} = wrapper->GetValue();
baton->result = {{ field.return.success }};
{% else %}
if (result->IsNumber()) {
baton->result = (int)result->ToNumber()->Value();
}
else {
baton->result = baton->defaultResult;
}
{% endif %}
}
else {
baton->result = baton->defaultResult;
}
{% endeach %}
baton->Done();
}
void {{ cppClassName }}::{{ field.name }}_promiseCompleted(bool isFulfilled, AsyncBaton *_baton, v8::Local<v8::Value> result) {
Nan::HandleScope scope;
{{ field.name|titleCase }}Baton* baton = static_cast<{{ field.name|titleCase }}Baton*>(_baton);
if (isFulfilled) {
//TODO: fix for void cases
{% if field.return.type == "void" %}
baton->Done();
{% else %}
{% each field|returnsInfo false true as _return %}
if (result.IsEmpty() || result->IsNativeError()) {
baton->result = {{ field.return.error }};
......@@ -247,7 +244,7 @@
if (result->IsNumber()) {
baton->result = (int)result->ToNumber()->Value();
}
else{
else {
baton->result = baton->defaultResult;
}
{% endif %}
......@@ -256,18 +253,59 @@
baton->result = baton->defaultResult;
}
{% endeach %}
}
else {
// promise was rejected
{{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>(baton->{% each field.args|argsInfo as arg %}
{% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %}
{% endeach %});
v8::Local<v8::Object> parent = instance->handle();
SetPrivate(parent, Nan::New("NodeGitPromiseError").ToLocalChecked(), result);
baton->Done();
{% endif %}
}
baton->result = {{ field.return.error }};
}
baton->Done();
void {{ cppClassName }}::{{ field.name }}_promiseCompleted(bool isFulfilled, AsyncBaton *_baton, v8::Local<v8::Value> result) {
Nan::HandleScope scope;
{{ field.name|titleCase }}Baton* baton = static_cast<{{ field.name|titleCase }}Baton*>(_baton);
{% if field.return.type == "void" %}
baton->Done();
{% else %}
if (isFulfilled) {
{% each field|returnsInfo false true as _return %}
if (result.IsEmpty() || result->IsNativeError()) {
baton->result = {{ field.return.error }};
}
else if (!result->IsNull() && !result->IsUndefined()) {
{% if _return.isOutParam %}
{{ _return.cppClassName }}* wrapper = Nan::ObjectWrap::Unwrap<{{ _return.cppClassName }}>(result->ToObject());
wrapper->selfFreeing = false;
*baton->{{ _return.name }} = wrapper->GetValue();
baton->result = {{ field.return.success }};
{% else %}
if (result->IsNumber()) {
baton->result = (int)result->ToNumber()->Value();
}
else{
baton->result = baton->defaultResult;
}
{% endif %}
}
else {
baton->result = baton->defaultResult;
}
{% endeach %}
}
else {
// promise was rejected
{% if isExtendedStruct %}
{{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>((({{cType}}_extended *)baton->self)->payload);
{% else %}
{{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>(baton->{% each field.args|argsInfo as arg %}
{% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %}
{% endeach %});
{% endif %}
v8::Local<v8::Object> parent = instance->handle();
SetPrivate(parent, Nan::New("NodeGitPromiseError").ToLocalChecked(), result);
baton->result = {{ field.return.error }};
}
baton->Done();
{% endif %}
}
{% endif %}
{% endif %}
......
......@@ -54,9 +54,13 @@ using namespace std;
{% if not field.ignore %}
{% if not field.isEnum %}
{% if field.isCallbackFunction %}
if (this->{{ field.name }}.HasCallback()) {
this->raw->{{ fields|payloadFor field.name }} = NULL;
}
if (this->{{ field.name }}.HasCallback()) {
{% if isExtendedStruct %}
(({{ cType }}_extended *)this->raw)->payload = NULL;
{% else %}
this->raw->{{ fields|payloadFor field.name }} = NULL;
{% endif %}
}
{% endif %}
{% endif %}
{% endif %}
......@@ -79,7 +83,12 @@ void {{ cppClassName }}::ConstructFields() {
// Set the static method call and set the payload for this function to be
// the current instance
this->raw->{{ field.name }} = NULL;
this->raw->{{ fields|payloadFor field.name }} = (void *)this;
//TODO: solve this problem
{% if isExtendedStruct %}
(({{ cType }}_extended *)this->raw)->payload = (void *)this;
{% else %}
this->raw->{{ fields|payloadFor field.name }} = (void *)this;
{% endif %}
{% elsif field.payloadFor %}
v8::Local<Value> {{ field.name }} = Nan::Undefined();
......
......@@ -24,7 +24,12 @@ using namespace node;
using namespace v8;
{%partial traits .%}
{% if isExtendedStruct %}
struct {{ cType }}_extended {
{{ cType }} raw;
void* payload;
};
{% endif %}
class {{ cppClassName }} : public NodeGitWrapper<{{ cppClassName }}Traits> {
// grant full access to base class
friend class NodeGitWrapper<{{ cppClassName }}Traits>;
......@@ -46,15 +51,27 @@ class {{ cppClassName }} : public NodeGitWrapper<{{ cppClassName }}Traits> {
static void {{ field.name }}_async(void *baton);
static void {{ field.name }}_promiseCompleted(bool isFulfilled, AsyncBaton *_baton, v8::Local<v8::Value> result);
struct {{ field.name|titleCase }}Baton : public AsyncBatonWithResult<{{ field.return.type }}> {
{% each field.args|argsInfo as arg %}
{{ arg.cType }} {{ arg.name}};
{% endeach %}
{% if field.return.type == 'void' %}
struct {{ field.name|titleCase }}Baton : public AsyncBatonWithNoResult{
{% each field.args|argsInfo as arg %}
{{ arg.cType }} {{ arg.name }};
{% endeach %}
{{ field.name|titleCase }}Baton()
: AsyncBatonWithNoResult() {
}
};
{% else %}
struct {{ field.name|titleCase }}Baton : public AsyncBatonWithResult<{{ field.return.type }}> {
{% each field.args|argsInfo as arg %}
{{ arg.cType }} {{ arg.name }};
{% endeach %}
{{ field.name|titleCase }}Baton(const {{ field.return.type }} &defaultResult)
: AsyncBatonWithResult<{{ field.return.type }}>(defaultResult) {
}
};
{{ field.name|titleCase }}Baton(const {{ field.return.type }} &defaultResult)
: AsyncBatonWithResult<{{ field.return.type }}>(defaultResult) {
}
};
{% endif %}
static {{ cppClassName }} * {{ field.name }}_getInstanceFromBaton (
{{ field.name|titleCase }}Baton *baton);
{% endif %}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment