const fs = require("fs"); const path = require("path"); var version = require("../../package.json").libgit2.version; var descriptor = require("./descriptor.json"); var libgit2 = require("./v" + version + ".json"); // This file was generated by @nkallen. var legacy = require("./new.json"); // Extracted types. var typeMap = require("./types.json"); // Structs or new types between v0.18 and v0.20. typeMap.__proto__ = { "git_filter_mode_t": { cpp: "Number", js: "Number" }, "const git_blame_hunk*": { cpp: "GitBlameHunk", js: "BlameHunk" }, "git_filter *": { cpp: "GitFilter", js: "Filter" }, "const git_status_entry *": { cpp: "StatusEntry", js: "StatusEntry" }, "const git_index_name_entry *": { cpp: "IndexNameEntry", js: "IndexNameEntry" }, // unsure "uint16_t": { cpp: "Integer", js: "Number" }, "git_blame_options": { cpp: "Integer", js: "Number" }, "git_blame_options *": { cpp: "Integer", js: "Number" }, "git_buf *": { cpp: "Buf", js: "Buf" }, "git_branch_iterator *": { cpp: "BranchIterator", js: "Iterator" }, "git_branch_iterator **": { cpp: "BranchIterator", js: "Iterator" }, "git_branch_t *": { cpp: "GitBranch", js: "Branch" } }; var files = []; function titleCase(str) { return str.split(/_|\//).map(function(val, index) { if (val.length) { return val[0].toUpperCase() + val.slice(1); } return val; }).join(""); } function camelCase(str) { return str.split(/_|\//).map(function(val, index) { if (val.length) { return index >= 1 ? val[0].toUpperCase() + val.slice(1) : val; } return val; }).join(""); } Object.keys(descriptor).forEach(function(fileName, index) { var file = descriptor[fileName]; // Constants. file.filename = fileName + ".h"; file.ignore = typeof file.ignore == "boolean" ? file.ignore : true; file.cppClassName = "Git" + titleCase(fileName); file.jsClassName = file.cppClassName; // Adjust to find the real the index. libgit2.files.some(function(currentFile, _index) { if (currentFile.filename === file.filename) { index = _index; return true; } }); if (file.cType === undefined) { if (libgit2.files[index].functions.length) { file.cType = libgit2.files[index].functions[0].split("_").slice(0, 2).join("_"); } } if (file.cType) { file.freeFunctionName = "git_" + fileName + "_free"; } // Doesn't actually exist. if (libgit2.files[index].functions.indexOf(file.freeFunctionName) === -1) { delete file.freeFunctionName; } var legacyFile = legacy.filter(function(currentFile) { return currentFile.filename === file.filename; })[0] || {}; if (file.jsClassName.indexOf("Git") === 0) { file.jsClassName = file.jsClassName.slice(3); } var uniqueTypes = []; var addType = function(arg) { if (!arg.type) { return; } if (arg.type.indexOf("git") === 0) { var val = arg.type.split(" ")[0].slice(4); if (uniqueTypes.indexOf(val) === -1 && descriptor[val]) { uniqueTypes.push(val); } } }; libgit2.files[index].functions.forEach(function(functionName) { var funcDescriptor = libgit2.functions[functionName]; var args = funcDescriptor.args || []; args.forEach(addType); addType(funcDescriptor.return.type); }); file.dependencies = uniqueTypes.map(function(file) { return "../include/" + file + ".h"; }); // Add to the type's list if it's new. typeMap["const " + "git_" + fileName + " *"] = typeMap["const " + "git_" + fileName + " **"] = typeMap["git_" + fileName + " *"] = typeMap["git_" + fileName + " **"] = typeMap["git_" + fileName] = { cpp: file.cppClassName, js: file.jsClassName }; file.functions = libgit2.files[index].functions.map(function(functionName, index) { var funcDescriptor = libgit2.functions[functionName]; var descriptor = legacyFile.functions ? legacyFile.functions[index] || {} : {}; var cType = file.cType || "git"; if (!functionName || !funcDescriptor) { return; } descriptor.cFunctionName = functionName; descriptor.ignore = true; var trimmedName = functionName.slice(cType.length + 1); if (trimmedName === "new") { trimmedName = "new2"; } descriptor.cppFunctionName = titleCase(trimmedName); descriptor.jsFunctionName = camelCase(trimmedName); // Add to the type's list if it's new. typeMap["const " + descriptor.cFunctionName + " *"] = typeMap[descriptor.cFunctionName + " *"] = typeMap[descriptor.cFunctionName] = { cpp: descriptor.cppFunctionName, js: descriptor.jsFunctionName }; var retVal = descriptor.return = {}; retVal.cType = funcDescriptor.return.type; var type = typeMap[retVal.cType]; retVal.cppClassName = type.cpp; retVal.jsClassName = type.js; var args = descriptor.args || []; var typeDescriptor = args.length ? args[0].type || "" : ""; var functionDescriptor = file.functions ? file.functions[functionName] || {} : {}; var isCtor = Boolean(functionDescriptor.isConstructorMethod); descriptor.isConstructorMethod = isCtor; // Set the prototype method argument. descriptor.isPrototypeMethod = !descriptor.isConstructorMethod; descriptor.args = funcDescriptor.args.map(function(arg) { var manualArgs = functionDescriptor.args ? functionDescriptor.args[arg.name] || {} : {}; function isSelf(arg) { return file.jsClassName === typeMap[arg.type].js; } if (typeMap[arg.type]) { return { name: arg.name, cType: arg.type, cppClassName: typeMap[arg.type].cpp, jsClassName: typeMap[arg.type].js, comment: arg.comment, isReturn: arg.name === "out" || arg.name.slice(-4) === "_out", isSelf: isSelf(arg) }; } return {}; }); return descriptor; }); files.push(file); }); fs.writeFileSync(path.join(__dirname, "types.json"), JSON.stringify(typeMap, null, 2)); fs.writeFileSync(path.join(__dirname, "compare.json"), JSON.stringify(files, null, 2));