UNPKG

widl-nan

Version:

Auto generate native C++ addon source code by parsing Web IDL definition

174 lines (143 loc) 5.5 kB
{{ 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 } } {{?}} {{~}}