node-gtk
Version:
GNOME Gtk+ bindings for NodeJS
148 lines (113 loc) • 3.56 kB
JavaScript
/*
* generate-surface.js
*/
const fs = require('fs')
const path = require('path')
const util = require('util')
const removeTrailingSpaces = require('remove-trailing-spaces')
const { unindent } = require('./indent.js')
const {
generateClassMethodSource,
generateSource,
parseFile,
getJSName,
} = require('./generator.js')
util.inspect.defaultOptions = { depth: 6 }
const base = {
name: 'Surface',
constructor: null,
functions: null,
isBase: true,
type: 'cairo_surface_t',
prefix: /cairo_[a-z0-9]+(_surface)?/,
destroy: 'cairo_surface_destroy',
filename: __filename,
dependencies: [
'font-options.h',
'surface.h',
'rectangle.h',
'rectangle-int.h',
],
}
generateCairoSurface()
function generateCairoSurface() {
const result = parseFile(path.join(__dirname, 'surface.nid'))
const declarations = result.declarations
console.log(declarations)
const namespaces = declarations.map((cur) => {
const name = cur.namespace.name
const options = name === base.name ? base : {
name,
constructor: null,
functions: null,
isBase: false,
type: base.type,
prefix: base.prefix,
base,
}
const allFunctions =
cur.namespace.declarations
.filter(d => d.function)
.map(d => {
const fn = d.function
fn.source = generateClassMethodSource(fn, options)
return fn
})
options.constructor = allFunctions.filter(fn => fn.attributes.constructor === true)[0]
options.functions = allFunctions.filter(fn => fn.attributes.constructor !== true)
return options
})
/* ImageSurface
* PDFSurface
* PostScriptSurface
* RecordingSurface
* Win32Surface
* SVGSurface
* QuartzSurface */
const header = generateHeader(namespaces)
const source = generateSource(base, namespaces)
fs.writeFileSync(path.join(__dirname, 'surface.h'), header)
fs.writeFileSync(path.join(__dirname, 'surface.cc'), source)
}
// Helpers
function generateHeader(namespaces) {
const classDeclarations = namespaces.map(generateClassDeclaration)
return removeTrailingSpaces(unindent(`
/* autogenerated by ${path.basename(__filename)} */
#pragma once
#include <nan.h>
#include <node.h>
#include <girepository.h>
#include <glib.h>
#include <cairo.h>
namespace GNodeJS {
namespace Cairo {
${classDeclarations.join('\n ')}
}; // Cairo
}; // GNodeJS
`))
}
function generateClassDeclaration(options) {
return `
class ${options.name}: public ${options.isBase ? 'Nan::ObjectWrap' : 'Surface'} {
public:
static Nan::Persistent<v8::FunctionTemplate> constructorTemplate;
static Nan::Persistent<v8::Function> constructor;
static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target);${options.isBase ? `
static void SetupTemplate();` : `
static void SetupTemplate(Local<v8::FunctionTemplate> parentTpl);`}
static Local<v8::FunctionTemplate> GetTemplate();
static Local<v8::Function> GetConstructor();
static NAN_METHOD(New);
${options.functions.map(fn => `static NAN_METHOD(${getFunctionJSName(fn)});`).join('\n ')}
${options.isBase ? `
${options.name}(cairo_surface_t* data);
~${options.name}();
cairo_surface_t* _data;
` : `
${options.name}(cairo_surface_t* data) : Surface(data) {};
`} };`
}
function getFunctionJSName(fn) {
return getJSName(fn.name, /cairo_[a-z0-9]+(_surface)?/)
}