UNPKG

2.7 kBJavaScriptView Raw
1const {Expr, Token, Setter, Expression, SetterExpression, SpliceSetterExpression, TokenTypeData} = require('./lang');
2const SimpleCompiler = require('./simple-compiler');
3const fs = require('fs');
4const os = require('os');
5const path = require('path');
6const {spawn, spawnSync} = require('child_process');
7const {extractTypes} = require('./flow-types');
8
9function spawnAsync(proc, args, options) {
10 return new Promise((resolve, reject) => {
11 const child = spawn(proc, args, options);
12 let results = '';
13 let err = '';
14 child.stdout.on('data', msg => {
15 results += msg;
16 });
17 child.stderr.on('data', msg => {
18 err += msg;
19 });
20 child.on('close', code => {
21 if (code === 0) {
22 resolve(results);
23 } else {
24 console.error(err);
25 reject(code);
26 }
27 });
28 });
29}
30
31const {splitSettersGetters, normalizeAndTagAllGetters} = require('./expr-tagging');
32
33class FlowCompiler extends SimpleCompiler {
34 constructor(model, options) {
35 const {getters, setters} = splitSettersGetters(model);
36 super({...model, ...normalizeAndTagAllGetters(getters, setters)}, options);
37 }
38
39 get template() {
40 return require('./templates/flow.js');
41 }
42
43 generateExpr(expr) {
44 const currentToken = expr instanceof Expression ? expr[0] : expr;
45 if (currentToken.hasOwnProperty('$id')) {
46 return `annotate_${expr[0].$id}(${super.generateExpr(expr)})`;
47 }
48 return super.generateExpr(expr);
49 }
50
51 buildExprFunctionsByTokenType(acc, expr) {
52 acc.push(`function annotate_${expr[0].$id} (src){return src}`);
53 super.buildExprFunctionsByTokenType(acc, expr);
54 }
55
56 compile() {
57 const src = super.compile();
58 console.log(src);
59 const tempDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'flow-'));
60 const tempFilename = path.join(tempDirectory, `${this.options.name}.js`);
61 const flowConfigFile = path.join(tempDirectory, '.flowconfig');
62 const srcBeforeFlowSuggest = `// @flow
63${this.options.flow};
64 ${src.replace(/\/\*::(.*?)\*\//g, '$1').replace(/\/\*:(.*?)\*\//g, ':$1')}
65`;
66 fs.writeFileSync(tempFilename, srcBeforeFlowSuggest);
67 const flowCliOptions = {cwd: tempDirectory + path.sep};
68 spawnSync(require.resolve('flow-bin/cli'), ['init'], flowCliOptions);
69 const postFlowSrc = spawnSync(require.resolve('flow-bin/cli'), ['suggest', tempFilename], flowCliOptions);
70 this.annotations = extractTypes(postFlowSrc);
71 console.log(JSON.stringify(this.annotations));
72 console.log(postFlowSrc);
73 fs.unlinkSync(flowConfigFile);
74 fs.unlinkSync(tempFilename);
75 fs.rmdirSync(tempDirectory);
76 return postFlowSrc;
77 }
78
79 get lang() {
80 return 'flow';
81 }
82}
83
84module.exports = FlowCompiler;