1// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4import * as fs from 'fs';
5import * as path from 'path';
6
7import {generateClosureBridge, GeneratedCode} from './generate_closure';
8import {filePathToTypeScriptSourceFile, walkTree} from './walk_tree';
9
10const chromeLicense = `// Copyright ${new Date().getFullYear()} The Chromium Authors. All rights reserved.
11// Use of this source code is governed by a BSD-style license that can be
12// found in the LICENSE file.
13`;
14
15export const writeToDisk = (inputFilePath: string, generatedCode: GeneratedCode) => {
16  const dir = path.dirname(inputFilePath);
17  const baseName = path.basename(inputFilePath, '.ts');
18  const outputFileName = `${baseName}_bridge.js`;
19
20  const interfaces = generatedCode.interfaces
21                         .map(interfacePart => {
22                           return interfacePart.join('\n');
23                         })
24                         .join('\n');
25  const classDeclaration = generatedCode.closureClass.join('\n');
26  const creatorFunction = generatedCode.creatorFunction.join('\n');
27
28  const relativeFilePath = path.relative(process.cwd(), inputFilePath);
29
30  const byHandWarning = `/**
31* WARNING: do not modify this file by hand!
32* it was automatically generated by the bridge generator
33* if you made changes to the source code and need to update this file, run:
34*  npm run generate-bridge-file ${relativeFilePath}
35*/
36`;
37
38  // extra \n to ensure ending with a linebreak at end of file
39  const finalCode = [chromeLicense, byHandWarning, interfaces, classDeclaration, creatorFunction].join('\n') + '\n';
40
41  fs.writeFileSync(path.join(dir, outputFileName), finalCode, {encoding: 'utf8'});
42
43  return {
44    output: path.join(dir, outputFileName),
45    code: finalCode,
46  };
47};
48
49export const parseTypeScriptComponent = (componentSourceFilePath: string) => {
50  const file = filePathToTypeScriptSourceFile(componentSourceFilePath);
51  const state = walkTree(file, componentSourceFilePath);
52  const generatedCode = generateClosureBridge(state);
53  return writeToDisk(componentSourceFilePath, generatedCode);
54};
55
56const main = (args: string[]) => {
57  const bridgeComponentPath = path.resolve(process.cwd(), args[0]);
58
59  if (!bridgeComponentPath || !fs.existsSync(bridgeComponentPath)) {
60    throw new Error(`Could not find bridgeComponent path ${bridgeComponentPath}`);
61  }
62
63  const {output} = parseTypeScriptComponent(bridgeComponentPath);
64
65  console.log('Wrote bridge file to', output);
66};
67
68if (require.main === module) {
69  main(process.argv.slice(2));
70}
71