Export anonymous functions in 2 steps, declare as variable and then assign to exports. (#39820)

* Preserve the variable name when exporting an arrow or anonymous function
 This allows the browser or node to properly name the (arrow) function

* Updated tests to reflect previous change

* Remove duplicated comment

* Transforms variable.initializer using moduleExpressionElementVisitor

* PR feedback: rbuckton
 - Use isArrowFunction and isFunctionExpression

* PR feedback: rbuckton
- Consider ClassExpresion, they can also be named based on the
  variable.
This commit is contained in:
Josejulio Martínez
2020-08-07 17:16:03 -07:00
committed by GitHub
parent 3328fdb2d8
commit 668bbc64ff
36 changed files with 111 additions and 42 deletions
+31 -2
View File
@@ -1195,6 +1195,7 @@ namespace ts {
if (hasSyntacticModifier(node, ModifierFlags.Export)) {
let modifiers: NodeArray<Modifier> | undefined;
let removeCommentsOnExpressions = false;
// If we're exporting these variables, then these just become assignments to 'exports.x'.
for (const variable of node.declarationList.declarations) {
@@ -1206,7 +1207,31 @@ namespace ts {
variables = append(variables, variable);
}
else if (variable.initializer) {
expressions = append(expressions, transformInitializedVariable(variable as InitializedVariableDeclaration));
if (!isBindingPattern(variable.name) && (isArrowFunction(variable.initializer) || isFunctionExpression(variable.initializer) || isClassExpression(variable.initializer))) {
const expression = factory.createAssignment(
setTextRange(
factory.createPropertyAccessExpression(
factory.createIdentifier("exports"),
variable.name
),
/*location*/ variable.name
),
factory.createIdentifier(getTextOfIdentifierOrLiteral(variable.name))
);
const updatedVariable = factory.createVariableDeclaration(
variable.name,
variable.exclamationToken,
variable.type,
visitNode(variable.initializer, moduleExpressionElementVisitor)
);
variables = append(variables, updatedVariable);
expressions = append(expressions, expression);
removeCommentsOnExpressions = true;
}
else {
expressions = append(expressions, transformInitializedVariable(variable as InitializedVariableDeclaration));
}
}
}
@@ -1215,7 +1240,11 @@ namespace ts {
}
if (expressions) {
statements = append(statements, setOriginalNode(setTextRange(factory.createExpressionStatement(factory.inlineExpressions(expressions)), node), node));
const statement = setOriginalNode(setTextRange(factory.createExpressionStatement(factory.inlineExpressions(expressions)), node), node);
if (removeCommentsOnExpressions) {
removeAllComments(statement);
}
statements = append(statements, statement);
}
}
else {
@@ -36,7 +36,8 @@ exports.a = void 0;
///<reference path='aliasUsedAsNameValue_1.ts' />
var mod = require("./aliasUsedAsNameValue_0");
var b = require("./aliasUsedAsNameValue_1");
exports.a = function () {
var a = function () {
//var x = mod.id; // TODO needed hack that mod is loaded
b.b(mod);
};
exports.a = a;
@@ -30,7 +30,8 @@ __exportStar(require("./thingB"), exports);
"use strict";
exports.__esModule = true;
exports.thing2 = void 0;
exports.thing2 = function (param) { return null; };
var thing2 = function (param) { return null; };
exports.thing2 = thing2;
//// [thingB.d.ts]
@@ -29,9 +29,10 @@ define("conditional_directive_field", ["require", "exports"], function (require,
"use strict";
exports.__esModule = true;
exports.build = void 0;
exports.build = function () {
var build = function () {
return null;
};
exports.build = build;
});
@@ -28,10 +28,11 @@ var context_1 = require("./context");
exports.context = (_a = {},
_a[context_1.Key] = 'bar',
_a);
exports.withContext = function (_a) {
var withContext = function (_a) {
var _b = context_1.Key, value = _a[_b];
return value;
};
exports.withContext = withContext;
//// [context.d.ts]
@@ -18,8 +18,10 @@ Point.zero = (): Point => Point(0, 0);
"use strict";
exports.__esModule = true;
exports.Rect = exports.Point = void 0;
exports.Point = function (x, y) { return ({ x: x, y: y }); };
exports.Rect = function (a, b) { return ({ a: a, b: b }); };
var Point = function (x, y) { return ({ x: x, y: y }); };
exports.Point = Point;
var Rect = function (a, b) { return ({ a: a, b: b }); };
exports.Rect = Rect;
exports.Point.zero = function () { return exports.Point(0, 0); };
@@ -25,7 +25,8 @@ exports["default"] = (function (suit, rank) { return ({ suit: suit, rank: rank }
"use strict";
exports.__esModule = true;
exports.lazyCard = void 0;
exports.lazyCard = function () { return Promise.resolve().then(function () { return require('./Card'); }).then(function (a) { return a["default"]; }); };
var lazyCard = function () { return Promise.resolve().then(function () { return require('./Card'); }).then(function (a) { return a["default"]; }); };
exports.lazyCard = lazyCard;
//// [Types.d.ts]
@@ -11,7 +11,8 @@ export const Foo = (opts: {
"use strict";
exports.__esModule = true;
exports.Foo = void 0;
exports.Foo = function (opts) { return ({}); };
var Foo = function (opts) { return ({}); };
exports.Foo = Foo;
//// [declarationEmitOptionalMethod.d.ts]
@@ -52,7 +52,7 @@ exports.someMethod = exports.Foo = exports.foo = void 0;
* comment1
* @param p
*/
exports.foo = function (p) {
var foo = function (p) {
return {
/**
* comment2
@@ -66,6 +66,7 @@ exports.foo = function (p) {
bar2: function (s) { }
};
};
exports.foo = foo;
var Foo = /** @class */ (function () {
function Foo() {
}
@@ -7,7 +7,8 @@ export const y = (x: Foo<string>) => 1
"use strict";
exports.__esModule = true;
exports.y = void 0;
exports.y = function (x) { return 1; };
var y = function (x) { return 1; };
exports.y = y;
//// [declarationEmitTypeAliasWithTypeParameters1.d.ts]
@@ -8,7 +8,8 @@ export const y = (x: Baa<number>) => 1
"use strict";
exports.__esModule = true;
exports.y = void 0;
exports.y = function (x) { return 1; };
var y = function (x) { return 1; };
exports.y = y;
//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
@@ -33,10 +33,11 @@ function useRef(current) {
return { current: current };
}
exports.useRef = useRef;
exports.useCsvParser = function () {
var useCsvParser = function () {
var parserRef = useRef(null);
return parserRef;
};
exports.useCsvParser = useCsvParser;
//// [index.d.ts]
@@ -39,7 +39,7 @@ var __extends = (this && this.__extends) || (function () {
})();
exports.__esModule = true;
exports.mixin = void 0;
exports.mixin = function (Base) {
var mixin = function (Base) {
return /** @class */ (function (_super) {
__extends(class_1, _super);
function class_1() {
@@ -49,6 +49,7 @@ exports.mixin = function (Base) {
return class_1;
}(Base));
};
exports.mixin = mixin;
//// [dom.d.ts]
@@ -57,7 +57,7 @@ var __assign = (this && this.__assign) || function () {
};
exports.__esModule = true;
exports.testRecFun = exports.updateIfChanged = void 0;
exports.updateIfChanged = function (t) {
var updateIfChanged = function (t) {
var reduce = function (u, update) {
var set = function (newU) { return Object.is(u, newU) ? t : update(newU); };
return Object.assign(function (key) {
@@ -69,8 +69,9 @@ exports.updateIfChanged = function (t) {
};
return reduce(t, function (t) { return t; });
};
exports.updateIfChanged = updateIfChanged;
// example from https://github.com/microsoft/TypeScript/issues/31605
exports.testRecFun = function (parent) {
var testRecFun = function (parent) {
return {
result: parent,
deeper: function (child) {
@@ -78,6 +79,7 @@ exports.testRecFun = function (parent) {
}
};
};
exports.testRecFun = testRecFun;
var p1 = exports.testRecFun({ one: '1' });
void p1.result.one;
var p2 = p1.deeper({ two: '2' });
@@ -23,7 +23,8 @@ export let ctor: IDirectiveLinkFn<number> | ConstructableA | IDirectivePrePost<n
"use strict";
exports.__esModule = true;
exports.ctor = exports.blah = void 0;
exports.blah = function (x) { };
var blah = function (x) { };
exports.blah = blah;
exports.ctor = /** @class */ (function () {
function class_1() {
}
@@ -20,7 +20,8 @@ sayHello(username());
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.username = void 0;
exports.username = () => 'username';
const username = () => 'username';
exports.username = username;
//// [index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
@@ -24,9 +24,10 @@ export const createService = <T>(
"use strict";
exports.__esModule = true;
exports.createService = void 0;
exports.createService = function (ServiceCtr) {
var createService = function (ServiceCtr) {
Object.keys(ServiceCtr).forEach(function (key) {
var method = (ServiceCtr)[key];
var __$daemonMode = method.__$daemonMode, __$action = method.__$action, id = method.id;
});
};
exports.createService = createService;
@@ -139,7 +139,7 @@ define(["require", "exports"], function (require, exports) {
return cl2;
}());
exports.cl2 = cl2;
exports.l = function () { return __awaiter(void 0, void 0, void 0, function () {
var l = function () { return __awaiter(void 0, void 0, void 0, function () {
var req;
return __generator(this, function (_a) {
switch (_a.label) {
@@ -151,4 +151,5 @@ define(["require", "exports"], function (require, exports) {
}
});
}); };
exports.l = l;
});
@@ -138,7 +138,7 @@ var cl2 = /** @class */ (function () {
return cl2;
}());
exports.cl2 = cl2;
exports.l = function () { return __awaiter(void 0, void 0, void 0, function () {
var l = function () { return __awaiter(void 0, void 0, void 0, function () {
var req;
return __generator(this, function (_a) {
switch (_a.label) {
@@ -150,3 +150,4 @@ exports.l = function () { return __awaiter(void 0, void 0, void 0, function () {
}
});
}); };
exports.l = l;
@@ -148,7 +148,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
return cl2;
}());
exports.cl2 = cl2;
exports.l = function () { return __awaiter(void 0, void 0, void 0, function () {
var l = function () { return __awaiter(void 0, void 0, void 0, function () {
var req;
return __generator(this, function (_a) {
switch (_a.label) {
@@ -160,4 +160,5 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
}
});
}); };
exports.l = l;
});
@@ -139,7 +139,7 @@ define(["require", "exports"], function (require, exports) {
return cl2;
}());
exports.cl2 = cl2;
exports.l = function () { return __awaiter(void 0, void 0, void 0, function () {
var l = function () { return __awaiter(void 0, void 0, void 0, function () {
var req;
return __generator(this, function (_a) {
switch (_a.label) {
@@ -151,4 +151,5 @@ define(["require", "exports"], function (require, exports) {
}
});
}); };
exports.l = l;
});
@@ -138,7 +138,7 @@ var cl2 = /** @class */ (function () {
return cl2;
}());
exports.cl2 = cl2;
exports.l = function () { return __awaiter(void 0, void 0, void 0, function () {
var l = function () { return __awaiter(void 0, void 0, void 0, function () {
var req;
return __generator(this, function (_a) {
switch (_a.label) {
@@ -150,3 +150,4 @@ exports.l = function () { return __awaiter(void 0, void 0, void 0, function () {
}
});
}); };
exports.l = l;
@@ -148,7 +148,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
return cl2;
}());
exports.cl2 = cl2;
exports.l = function () { return __awaiter(void 0, void 0, void 0, function () {
var l = function () { return __awaiter(void 0, void 0, void 0, function () {
var req;
return __generator(this, function (_a) {
switch (_a.label) {
@@ -160,4 +160,5 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
}
});
}); };
exports.l = l;
});
@@ -71,7 +71,8 @@ define(["require", "exports"], function (require, exports) {
}
}
exports.cl2 = cl2;
exports.l = () => __awaiter(void 0, void 0, void 0, function* () {
const l = () => __awaiter(void 0, void 0, void 0, function* () {
const req = yield new Promise((resolve_5, reject_5) => { require(['./test'], resolve_5, reject_5); }); // FIVE
});
exports.l = l;
});
@@ -70,6 +70,7 @@ class cl2 {
}
}
exports.cl2 = cl2;
exports.l = () => __awaiter(void 0, void 0, void 0, function* () {
const l = () => __awaiter(void 0, void 0, void 0, function* () {
const req = yield Promise.resolve().then(() => require('./test')); // FIVE
});
exports.l = l;
@@ -80,7 +80,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}
}
exports.cl2 = cl2;
exports.l = () => __awaiter(void 0, void 0, void 0, function* () {
const l = () => __awaiter(void 0, void 0, void 0, function* () {
const req = yield __syncRequire ? Promise.resolve().then(() => require('./test')) : new Promise((resolve_5, reject_5) => { require(['./test'], resolve_5, reject_5); }); // FIVE
});
exports.l = l;
});
@@ -94,13 +94,14 @@ exports.__esModule = true;
exports.tree = exports.MyClass = exports.MySFC = void 0;
/** @jsx predom */
var renderer2_1 = require("./renderer2");
exports.MySFC = function (props) { return renderer2_1.predom("p", null,
var MySFC = function (props) { return renderer2_1.predom("p", null,
props.x,
" + ",
props.y,
" = ",
props.x + props.y,
_this.props.children); };
exports.MySFC = MySFC;
var MyClass = /** @class */ (function () {
function MyClass(props) {
this.props = props;
@@ -47,7 +47,7 @@ exports.Serializable = void 0;
/**
* Plain mixin where the superclass must be Initable
*/
exports.Serializable = function (SuperClass) {
var Serializable = function (SuperClass) {
var LocalMixin = function (InnerSuperClass) {
return /** @class */ (function (_super) {
__extends(SerializableLocal, _super);
@@ -60,6 +60,7 @@ exports.Serializable = function (SuperClass) {
var ResultClass = LocalMixin(SuperClass);
return ResultClass;
};
exports.Serializable = Serializable;
var AMixin = function (SuperClass) {
var SomeHowOkay = /** @class */ (function (_super) {
__extends(A, _super);
@@ -46,7 +46,8 @@ __exportStar(require("./account"), exports);
"use strict";
exports.__esModule = true;
exports.func = void 0;
exports.func = function (account, acc2) { };
var func = function (account, acc2) { };
exports.func = func;
//// [account.d.ts]
@@ -18,10 +18,13 @@ ignoreJsdoc.extra = 111
"use strict";
exports.__esModule = true;
exports.ignoreJsdoc = exports.inlined = exports.interfaced = void 0;
exports.interfaced = function () { return true; };
var interfaced = function () { return true; };
exports.interfaced = interfaced;
exports.interfaced.num = 123;
exports.inlined = function () { return true; };
var inlined = function () { return true; };
exports.inlined = inlined;
exports.inlined.nun = 456;
exports.ignoreJsdoc = function () { return true; };
var ignoreJsdoc = function () { return true; };
exports.ignoreJsdoc = ignoreJsdoc;
/** @type {string} make sure to ignore jsdoc! */
exports.ignoreJsdoc.extra = 111;
@@ -15,7 +15,8 @@ export const thing = () => parse();
exports.__esModule = true;
exports.thing = void 0;
var url_1 = require("url");
exports.thing = function () { return url_1.parse(); };
var thing = function () { return url_1.parse(); };
exports.thing = thing;
//// [usage.d.ts]
@@ -44,7 +44,7 @@ export const narrowToLiterals = (str: string) => {
"use strict";
exports.__esModule = true;
exports.narrowToStringOrNumber = exports.narrowToString = exports.narrowToLiterals = void 0;
exports.narrowToLiterals = function (str) {
var narrowToLiterals = function (str) {
switch (str) {
case 'abc': {
// inferred type as `abc`
@@ -54,7 +54,8 @@ exports.narrowToLiterals = function (str) {
return 'defaultValue';
}
};
exports.narrowToString = function (str, someOtherStr) {
exports.narrowToLiterals = narrowToLiterals;
var narrowToString = function (str, someOtherStr) {
switch (str) {
case 'abc': {
// inferred type should be `abc`
@@ -68,7 +69,8 @@ exports.narrowToString = function (str, someOtherStr) {
return 'defaultValue';
}
};
exports.narrowToStringOrNumber = function (str, someNumber) {
exports.narrowToString = narrowToString;
var narrowToStringOrNumber = function (str, someNumber) {
switch (str) {
case 'abc': {
// inferred type should be `abc`
@@ -82,3 +84,4 @@ exports.narrowToStringOrNumber = function (str, someNumber) {
return 'defaultValue';
}
};
exports.narrowToStringOrNumber = narrowToStringOrNumber;
View File
+2 -1
View File
@@ -7,5 +7,6 @@ define(["require", "exports"], function (require, exports) {
var _this = this;
exports.__esModule = true;
exports.x = void 0;
exports.x = function () { return _this.window; };
var x = function () { return _this.window; };
exports.x = x;
});
@@ -20,7 +20,8 @@ export let y = () => x
exports.__esModule = true;
exports.y = exports.x = exports.$ = void 0;
exports.$ = 1;
exports.y = function () { return exports.x; };
var y = function () { return exports.x; };
exports.y = y;
//// [app.d.ts]
@@ -72,7 +72,7 @@ exports.obj = {
return p;
}
};
exports.classExpression = class {
const classExpression = class {
method1(p) {
return p;
}
@@ -80,6 +80,7 @@ exports.classExpression = class {
return p;
}
};
exports.classExpression = classExpression;
function funcInferredReturnType(obj) {
return obj;
}