widl-nan
Version:
Auto generate native C++ addon source code by parsing Web IDL definition
174 lines (143 loc) • 5.5 kB
Plain Text
{{ var className = "Nan" + it.name; }}
{{#def.idlType}}
{{#def.buildValidEnumValuesList}}
{{#def.impl}}
{{#def.enum}}
{{#def.extractV8Value}}
{{#def.callback}}
{{#def.overload}}
{{#def.array}}
{{#def.members}}
{{
var callback = extractAllCallbackMethod(it);
var hasCallback = callback.methods.length > 0;
var allMethodMembers = getAllMethodMembers(it);
}}
{{~ allMethodMembers :p:i }}
{{
var unwrapStr = 'auto myself = ObjectWrap::Unwrap<' + className + '>(info.Holder());';
var functionCallPrefix = 'myself->impl_->';
var isStaticMethod = (p.static === true);
if ( isStaticMethod ) {
functionCallPrefix = it.name + '::';
unwrapStr = '';
}
var generateMethod = isFirstMethodInOverloadList(it, p, i);
var overloadList = it.operationMap[p.name];
var methodName = p.name;
var methodOverloadList = [];
overloadList.forEach(o => {
methodOverloadList.push(allMethodMembers[o.index]);
});
}}
{{? generateMethod}}
NAN_METHOD({{=className}}::{{=methodName}}) {
{{=unwrapStr}}
info.GetReturnValue().Set(Nan::Undefined());
{{~ methodOverloadList :method:index}}
{{
var numArgs = method.arguments.length;
var elseIf = '';
if (index > 0) {
elseIf = 'else ';
}
}}
{{=elseIf}}if ({{=generateArgsIfConditionStr(method, it.refTypeMap, callback)}}) {
// Method: name = {{=method.name}}, taking {{=numArgs}} argument(s)
{{ var args = []; }}
{{~ method.arguments :q:j}}
{{
args.push('arg' + j);
}}
{{? isCallback(q.idlType, callback) }}
{{var callbackHelperClassName = getCallbackHelperClassName(q.idlType.idlType);}}
auto function{{=j}} = {{=extractArgument(q.idlType, it.refTypeMap, callback)}}(info[{{=j}}]);
{{=callbackHelperClassName}}* arg{{=j}} = new {{=callbackHelperClassName}}();
arg{{=j}}->Reset(function{{=j}}, info.This());
{{?? isInterface(q.idlType, it.refTypeMap) }}
// Convert to impl {{=q.idlType.idlType}} pointer
auto nanArg{{=j}} = {{=extractArgument(q.idlType, it.refTypeMap)}}(info[{{=j}}]);
auto arg{{=j}} = *(ObjectWrap::Unwrap<Nan{{=q.idlType.idlType}}>(nanArg{{=j}})->{{=generateGetImplMethodName(q.idlType.idlType)}}());
{{?? true}}
{{
var defaultValueStr = '';
if (q.default && q.default.value) {
if (q.default.type === 'string' || q.default.type === 'DOMString') {
defaultValueStr = ', "' + q.default.value + '"';
} else {
defaultValueStr = ', ' + q.default.value;
}
}
}}
auto arg{{=j}} = {{=extractArgument(q.idlType, it.refTypeMap)}}(info[{{=j}}]{{=defaultValueStr}});
{{?}}
{{
var enumCheck = isEnumType(q.idlType, it.refTypeMap);
var enumDef = getEnumDef(q.idlType, it.refTypeMap);
var enumName = enumDef.name;
}}
{{? enumCheck }}
// Valid enum values for parameter info{{=j}}, original IDL type: {{=enumName}}
const char* VALID_ENUM_{{=(enumName.toUpperCase())}}_INFO{{=j}}[] = { {{=buildValidEnumValuesList(enumDef)}} };
ThrowIfEnumValueNotValid(arg{{=j}}, VALID_ENUM_{{=(enumName.toUpperCase())}}_INFO{{=j}}, {{=q.name}}, {{=enumName}});
{{?}}
{{~}}
{{
if (method.idlType.generic === 'Promise') {
/*args.push('info.GetIsolate()');*/
}
var argStr = args.join(', ');
}}
{{? method.idlType.generic === 'Promise' }}
// Return promise
{{=functionCallPrefix}}SetJavaScriptThis(info.This());
auto promise = {{=functionCallPrefix}}{{=methodName}}({{=argStr}});
info.GetReturnValue().Set(promise);
{{?? method.idlType.idlType === 'void' }}
// Return type is void
{{=functionCallPrefix}}{{=methodName}}({{=argStr}});
info.GetReturnValue().Set(Nan::Undefined());
{{?? method.idlType.idlType === 'String' || method.idlType.idlType === 'DOMString' }}
// Return type is string
auto value = {{=functionCallPrefix}}{{=methodName}}({{=argStr}});
info.GetReturnValue().Set(Nan::New(value).ToLocalChecked());
{{?? method.idlType.idlType === 'ArrayBuffer' }}
// Return type is ArrayBuffer
ArrayBuffer arrayBuffer = {{=functionCallPrefix}}{{=methodName}}({{=argStr}});
v8::Local<v8::Object> value;
if (Nan::NewBuffer(arrayBuffer.data, arrayBuffer.size).ToLocal(&value))
info.GetReturnValue().Set(value);
{{?? isInterface(method.idlType, it.refTypeMap)}}
// Return type is an interface object
auto implObj = {{=functionCallPrefix}}{{=methodName}}({{=argStr}});
{{ var retType = method.idlType.idlType; }}
if (!implObj) {
info.GetReturnValue().Set(Nan::Undefined());
} else {
auto value = Nan{{=retType}}::NewInstance();
ObjectWrap::Unwrap<Nan{{=retType}}>(value)->Set{{=retType}}Impl(implObj);
info.GetReturnValue().Set(value);
}
{{?? isDictionary(method.idlType, it.refTypeMap)}}
// Return type is a dictionary object
auto value = {{=functionCallPrefix}}{{=methodName}}({{=argStr}});
info.GetReturnValue().Set(static_cast<v8::Local<v8::Object>>(value));
{{?? isArray(method.idlType) }}
auto value = {{=functionCallPrefix}}{{=methodName}}({{=argStr}});
info.GetReturnValue().Set(static_cast<v8::Local<v8::Array>>(value));
{{?? isTypedArray(method.idlType) }}
auto value = {{=functionCallPrefix}}{{=methodName}}({{=argStr}});
info.GetReturnValue().Set(value.GetTypedArray());
{{?? true }}
// Primitive types (int, double ...)
auto value = {{=functionCallPrefix}}{{=methodName}}({{=argStr}});
info.GetReturnValue().Set(Nan::New(value));
{{?}}
} // Closing bracket of 'if (info.Length() == {{=numArgs}})'
{{~}}
else {
// TODO: handle no-match by modifying template nanCxxImplMethod.def
}
}
{{?}}
{{~}}