1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! ES2015 Arrow Functions
//!
//! This plugin transforms arrow functions (`() => {}`) to function expressions (`function () {}`).
//!
//! > This plugin is included in `preset-env`, in ES2015
//!
//! ## Missing features
//!
//! Implementation is incomplete at present. Still TODO:
//!
//! * `spec` option.
//! * Handle `arguments` in arrow functions.
//! * Handle `new.target` in arrow functions.
//! * Handle arrow function in function params (`function f(g = () => this) {}`).
//! Babel gets this wrong: <https://babeljs.io/repl#?code_lz=GYVwdgxgLglg9mABMOcAUAPRBeRaCUOAfIlABYwDOhA3gL5A&presets=&externalPlugins=%40babel%2Fplugin-transform-arrow-functions%407.24.7>
//! * Error on arrow functions in class properties.
//! <https://babeljs.io/repl#?code_lz=MYGwhgzhAEDC0G8BQ1oDMD2HoF5oAoBKXAPmgBcALASwgG4kBfJIA&presets=&externalPlugins=%40babel%2Fplugin-transform-arrow-functions%407.24.7>
//! or we can support it:
//! `class C { x = () => this; }`
//! -> `class C { x = (function(_this) { return () => _this; })(this); }`
//! * Error on `super` in arrow functions.
//! <https://babeljs.io/repl#?code_lz=MYGwhgzhAEBiD29oG8C-AoUkYCEwCdoBTADwBciA7AExgSWXWmgFsiyALeagCgEoUTZtHzsArvkrR-0ALwA-aBDEAHIvgB0AM0QBuIRgxA&presets=&externalPlugins=%40babel%2Fplugin-transform-arrow-functions%407.24.7>
//!
//! ## Example
//!
//! Input:
//! ```js
//! var a = () => {};
//! var a = b => b;
//!
//! const double = [1, 2, 3].map(num => num * 2);
//! console.log(double); // [2,4,6]
//!
//! var bob = {
//! name: "Bob",
//! friends: ["Sally", "Tom"],
//! printFriends() {
//! this.friends.forEach(f => console.log(this.name + " knows " + f));
//! },
//! };
//! console.log(bob.printFriends());
//! ```
//!
//! Output:
//! ```js
//! var a = function() {};
//! var a = function(b) { return b; };
//!
//! const double = [1, 2, 3].map(function(num) {
//! return num * 2;
//! });
//! console.log(double); // [2,4,6]
//!
//! var bob = {
//! name: "Bob",
//! friends: ["Sally", "Tom"],
//! printFriends() {
//! var _this = this;
//! this.friends.forEach(function(f) {
//! return console.log(_this.name + " knows " + f);
//! });
//! },
//! };
//! console.log(bob.printFriends());
//! ```
//!
//! ## Options
//!
//! ### `spec`
//!
//! `boolean`, defaults to `false`.
//!
//! This option enables the following:
//! * Wrap the generated function in .bind(this) and keeps uses of this inside the function as-is,
//! instead of using a renamed this.
//! * Add a runtime check to ensure the functions are not instantiated.
//! * Add names to arrow functions.
//!
//! #### Example
//!
//! Using spec mode with the above example produces:
//!
//! ```js
//! var _this = this;
//!
//! var a = function a() {
//! babelHelpers.newArrowCheck(this, _this);
//! }.bind(this);
//! var a = function a(b) {
//! babelHelpers.newArrowCheck(this, _this);
//! return b;
//! }.bind(this);
//!
//! const double = [1, 2, 3].map(
//! function(num) {
//! babelHelpers.newArrowCheck(this, _this);
//! return num * 2;
//! }.bind(this)
//! );
//! console.log(double); // [2,4,6]
//!
//! var bob = {
//! name: "Bob",
//! friends: ["Sally", "Tom"],
//! printFriends() {
//! var _this2 = this;
//! this.friends.forEach(
//! function(f) {
//! babelHelpers.newArrowCheck(this, _this2);
//! return console.log(this.name + " knows " + f);
//! }.bind(this)
//! );
//! },
//! };
//! console.log(bob.printFriends());
//! ```
//!
//! ## Implementation
//!
//! The implementation is placed in [`crate::common::arrow_function_converter::ArrowFunctionConverter`],
//! which can be used in other plugins.
//!
//! ## References:
//!
//! * Babel plugin implementation: <https://github.com/babel/babel/blob/v7.26.2/packages/babel-plugin-transform-arrow-functions>
//! * Arrow function specification: <https://tc39.es/ecma262/#sec-arrow-function-definitions>
use Deserialize;
use Traverse;
use crateTransformState;
/// Options for the ES2015 arrow-function transform.