Skip to content

emit type parameters#4

Open
milahu wants to merge 1 commit intoMrMaxie:masterfrom
milahu:emit-type-parameters
Open

emit type parameters#4
milahu wants to merge 1 commit intoMrMaxie:masterfrom
milahu:emit-type-parameters

Conversation

@milahu
Copy link

@milahu milahu commented Dec 20, 2020

sample code

// auto-generate interface functions (glue code) from typescript *.d.ts types file

const TSTypesParser = require('ts-types-parser');
const parser = new TSTypesParser();

// input + output file
parser.setSource('node_modules/typescript/lib/lib.dom.d.ts');
parser.setTarget('interface.out.js');

// entry point
parser.mainType('CanvasRenderingContext2D');

const result = {};

parser.on('level-up', ({ name, path, type, parameters }) => {
  if (parameters) {
    // method
    const parm_names = parameters.map(p => p.name);
    if (name in result) result[name].push(parm_names);
    else result[name] = [ parm_names ];
  }
  else result[name] = null; // property
});

parser.on('done', () => {
  if (console._log) {
    // restore output
    console.log = console._log;
    console.warn = console._warn;
  }
  // file header
  parser.write(`// this file was auto-generated with ts-types-parser\n`);
  if (parser._sources.length == 1)
    parser.write(`// source file: ${parser._sources[0]}`);
  else {
    parser.write(`// source files:`);
    parser._sources.forEach(s => {
      parser.write(`//   ${s}`);
    });
  }
  parser.write(`// main type: ${parser._mainType}`);
  parser.write(`\nmodule.exports = {\n`);

  Object.keys(result).forEach(name => {
    const parameters_variants = result[name];
    if (Array.isArray(parameters_variants)) {
      // method
      if (parameters_variants.length == 1) {
        // no overloads
        const v = parameters_variants[0];
        if (v.length == 0) {
          parser.write(`${name}: (ctx) => ctx.${name}(),`);
        }
        else {
          const parms = v.join(', ');
          parser.write(`${name}: (ctx, { ${parms} }) => ctx.${name}(${parms}),`);
        }
      }
      else {
        // multiple method signatures
        parser.write(`${name}: (ctx, parms) => {`);
        parser.write(`  const n = Object.keys(parms).length;`);
        parameters_variants.sort((a, b) => (a.length - b.length));
        parameters_variants.forEach(v => {
          parser.write(`  if (n == ${v.length}) {`);
          if (v.length == 0) {
            parser.write(`    return ctx.${name}();`);
          } else {
            const parms = v.join(', ');
            parser.write(`    const { ${parms} } = parms;`);
            parser.write(`    return ctx.${name}(${parms});`);
          }
          parser.write(`  }`);
        });
        parser.write(`},`);
      }
    }
    else {
      // property setter
      // TODO property getter?
      parser.write(`${name}: (ctx, { value }) => ctx.${name} = value,`);
    }
  });
  parser.write(`\n};`);
})

if (1) {
  // disable output from parser.run
  console._log = console.log;
  console._warn = console.warn;
  console.log = () => {};
  console.warn = () => {}; 
}

parser.run();

sample result

canvas: (ctx, { value }) => ctx.canvas = value,
restore: (ctx) => ctx.restore(),
save: (ctx) => ctx.save(),
getTransform: (ctx) => ctx.getTransform(),
resetTransform: (ctx) => ctx.resetTransform(),
rotate: (ctx, { angle }) => ctx.rotate(angle),
scale: (ctx, { x, y }) => ctx.scale(x, y),
setTransform: (ctx, parms) => {
  const n = Object.keys(parms).length;
  if (n == 1) {
    const { transform } = parms;
    return ctx.setTransform(transform);
  }
  if (n == 6) {
    const { a, b, c, d, e, f } = parms;
    return ctx.setTransform(a, b, c, d, e, f);
  }
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant