UNPKG

3.39 kBJavaScriptView Raw
1"use strict";
2var types = require("babel-types");
3var template = require("babel-template");
4// Remove null args at the end of method or constructor calls.
5// This may conflict in some situations when comparing null to undefined, see #231,
6// but if disabled can cause problems with some APIs that use options to represent optional
7// arguments like CanvasRenderingContext2D.fill: ?fillRule: string -> unit (fails if passed null).
8function removeNullTailArgs(path) {
9 if (Array.isArray(path.node.arguments)) {
10 for (var i = path.node.arguments.length - 1; i >= 0; i--) {
11 if (types.isNullLiteral(path.node.arguments[i]))
12 path.node.arguments.splice(i, 1);
13 else
14 break;
15 }
16 }
17}
18/**
19 * Removes unnecessary null statements and null arguments at the end
20 * of method/constructor calls, as these usually represent optional
21 * arguments set to None by F# compiler and may conflict with some JS APIs.
22 * This plugin must come after transformMacroExpressions (see #377).
23 */
24exports.removeUnneededNulls = {
25 visitor: {
26 // Remove `null;` statements (e.g. at the end of constructors)
27 ExpressionStatement: function (path) {
28 if (types.isNullLiteral(path.node.expression))
29 path.remove();
30 }
31 }
32};
33/**
34 * When Babel compiles class methods to ES5 it keeps the function named
35 * even if it's a function expression, this is causing problems with Rollup.
36 */
37exports.removeFunctionExpressionNames = {
38 visitor: {
39 FunctionExpression: function (path) {
40 path.node.id = null;
41 }
42 }
43};
44/**
45 * Custom plugin to simulate macro expressions.
46 */
47exports.transformMacroExpressions = {
48 visitor: {
49 StringLiteral: function (path) {
50 var node = path.node;
51 if (!node.macro || !node.value) {
52 return;
53 }
54 var buildArgs = {}, macro = node.value;
55 try {
56 var args = node.args;
57 for (var i = 0; i < args.length; i++) {
58 buildArgs["$" + i] = args[i];
59 }
60 macro = macro
61 .replace(/\$(\d+)\.\.\./, function (m, i) {
62 var rep = [], j = parseInt(i);
63 for (; j < args.length; j++) {
64 rep.push("$" + j);
65 }
66 return rep.join(",");
67 })
68 .replace(/\{\{\$(\d+)\?(.*?)\:(.*?)\}\}/g, function (_, g1, g2, g3) {
69 var i = parseInt(g1);
70 return i < args.length && args[i].value ? g2 : g3;
71 })
72 .replace(/\{\{([^\}]*\$(\d+).*?)\}\}/g, function (_, g1, g2) {
73 var i = parseInt(g2);
74 return i < args.length ? g1 : "";
75 });
76 var buildMacro = template(macro);
77 path.replaceWithMultiple(buildMacro(buildArgs));
78 }
79 catch (err) {
80 console.log("BABEL ERROR: Failed to parse macro: " + macro);
81 console.log("MACRO ARGUMENTS: " + Object.getOwnPropertyNames(buildArgs).join());
82 console.log(err.message);
83 process.exit(1);
84 }
85 }
86 }
87};