| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 | 
const fs = require('fs');const path = require('path');const stream = require('stream');const split2 = require('split2');const pumpify = require('pumpify');const cprotoParser = require('./reader-cproto-parser.js');const docParser = require('./reader-doc-parser.js');const DOC_FILE = path.resolve(__dirname, '..', 'cephes', 'cephes.txt');const INTERNAL_CEPHES_FUNCTIONS = new Set([  'hyp2f0', 'onef2', 'threef0']);class MergeDocumentation extends stream.Transform {  constructor() {    super({ objectMode: true });    this._prototypes = new Map();    this._documentationEnded = false;    this._documentation = [];    this._documentationStream = fs.createReadStream(DOC_FILE)      .pipe(docParser())      .on('data', (doc) => this._documentation.push(doc))      .once('end', (err) => this._documentationEnded = true)      .on('error', (err) => this.emit('error', err));  }  _transform(proto, encoding, done) {    this._prototypes.set(proto.functionName, proto);    done(null);  }  _finish(done) {    // Validate that no documentation is missing    const documentationParts = new Set(      this._documentation.map((doc) => doc.functionName)    );    for (const protoFunctionName of this._prototypes.keys()) {      if (INTERNAL_CEPHES_FUNCTIONS.has(protoFunctionName)) continue;      if (!documentationParts.has(protoFunctionName)) {        throw new Error(`documentation for ${protoFunctionName} is missing`);      }    }    // Merge data    // The order of the documentation stream is meaninful, so use the    // documentation as the order and merge in the prototypes.    for (const doc of this._documentation) {      if (INTERNAL_CEPHES_FUNCTIONS.has(doc.functionName)) continue;      if (this._prototypes.has(doc.functionName)) {        this.push(          Object.assign({}, doc, this._prototypes.get(doc.functionName))        );      }    }    done(null);  }  _flush(done) {    if (this._documentationEnded) {      process.nextTick(() => this._finish(done));    } else {      this._documentationStream.once('end', () => this._finish(done));    }  }}function parser() {  return pumpify.obj(    cprotoParser(),    new MergeDocumentation()  );}module.exports = parser;
 |