Skip to content

Commit f0a7f99

Browse files
committed
Indirect calls for imported functions
1 parent 5be0d71 commit f0a7f99

File tree

175 files changed

+10922
-333
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

175 files changed

+10922
-333
lines changed

package-lock.json

Lines changed: 10547 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compiler/emitter.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,7 +2473,17 @@ namespace ts {
24732473
}
24742474

24752475
function emitCallExpression(node: CallExpression) {
2476+
const indirectCall = getEmitFlags(node) & EmitFlags.IndirectCall;
2477+
if (indirectCall) {
2478+
writePunctuation("(");
2479+
writeLiteral("0");
2480+
writePunctuation(",");
2481+
writeSpace();
2482+
}
24762483
emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess);
2484+
if (indirectCall) {
2485+
writePunctuation(")");
2486+
}
24772487
emit(node.questionDotToken);
24782488
emitTypeArguments(node, node.typeArguments);
24792489
emitExpressionList(node, node.arguments, ListFormat.CallExpressionArguments, parenthesizer.parenthesizeExpressionForDisallowedComma);
@@ -2488,7 +2498,17 @@ namespace ts {
24882498
}
24892499

24902500
function emitTaggedTemplateExpression(node: TaggedTemplateExpression) {
2501+
const indirectCall = getEmitFlags(node) & EmitFlags.IndirectCall;
2502+
if (indirectCall) {
2503+
writePunctuation("(");
2504+
writeLiteral("0");
2505+
writePunctuation(",");
2506+
writeSpace();
2507+
}
24912508
emitExpression(node.tag, parenthesizer.parenthesizeLeftSideOfAccess);
2509+
if (indirectCall) {
2510+
writePunctuation(")");
2511+
}
24922512
emitTypeArguments(node, node.typeArguments);
24932513
writeSpace();
24942514
emitExpression(node.template);

src/compiler/transformers/module/module.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ namespace ts {
3333
const previousOnEmitNode = context.onEmitNode;
3434
context.onSubstituteNode = onSubstituteNode;
3535
context.onEmitNode = onEmitNode;
36+
context.enableSubstitution(SyntaxKind.CallExpression); // Substitute calls to imported/exported symbols to avoid incorrect `this`.
37+
context.enableSubstitution(SyntaxKind.TaggedTemplateExpression); // Substitute calls to imported/exported symbols to avoid incorrect `this`.
3638
context.enableSubstitution(SyntaxKind.Identifier); // Substitutes expression identifiers with imported/exported symbols.
3739
context.enableSubstitution(SyntaxKind.BinaryExpression); // Substitutes assignments to exported symbols.
3840
context.enableSubstitution(SyntaxKind.PrefixUnaryExpression); // Substitutes updates to exported symbols.
@@ -47,6 +49,8 @@ namespace ts {
4749
let currentModuleInfo: ExternalModuleInfo; // The ExternalModuleInfo for the current file.
4850
let noSubstitution: boolean[]; // Set of nodes for which substitution rules should be ignored.
4951
let needUMDDynamicImportHelper: boolean;
52+
const zeroLiteral = factory.createNumericLiteral(0);
53+
setEmitFlags(zeroLiteral, EmitFlags.Immutable);
5054

5155
return chainBundle(context, transformSourceFile);
5256

@@ -1741,6 +1745,10 @@ namespace ts {
17411745
switch (node.kind) {
17421746
case SyntaxKind.Identifier:
17431747
return substituteExpressionIdentifier(node as Identifier);
1748+
case SyntaxKind.CallExpression:
1749+
return substituteCallExpression(node as CallExpression);
1750+
case SyntaxKind.TaggedTemplateExpression:
1751+
return substituteTaggedTemplateExpression(node as TaggedTemplateExpression);
17441752
case SyntaxKind.BinaryExpression:
17451753
return substituteBinaryExpression(node as BinaryExpression);
17461754
case SyntaxKind.PostfixUnaryExpression:
@@ -1751,6 +1759,43 @@ namespace ts {
17511759
return node;
17521760
}
17531761

1762+
function substituteCallExpression(node: CallExpression) {
1763+
if (isIdentifier(node.expression)) {
1764+
const expression = substituteExpressionIdentifier(node.expression);
1765+
noSubstitution[getNodeId(expression)] = true;
1766+
if (!isIdentifier(expression)) {
1767+
return addEmitFlags(
1768+
factory.updateCallExpression(node,
1769+
expression,
1770+
/*typeArguments*/ undefined,
1771+
node.arguments
1772+
),
1773+
EmitFlags.IndirectCall
1774+
);
1775+
1776+
}
1777+
}
1778+
return node;
1779+
}
1780+
1781+
function substituteTaggedTemplateExpression(node: TaggedTemplateExpression) {
1782+
if (isIdentifier(node.tag)) {
1783+
const tag = substituteExpressionIdentifier(node.tag);
1784+
noSubstitution[getNodeId(tag)] = true;
1785+
if (!isIdentifier(tag)) {
1786+
return addEmitFlags(
1787+
factory.updateTaggedTemplateExpression(node,
1788+
tag,
1789+
/*typeArguments*/ undefined,
1790+
node.template
1791+
),
1792+
EmitFlags.IndirectCall
1793+
);
1794+
}
1795+
}
1796+
return node;
1797+
}
1798+
17541799
/**
17551800
* Substitution for an Identifier expression that may contain an imported or exported
17561801
* symbol.

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6728,6 +6728,7 @@ namespace ts {
67286728
/*@internal*/ NeverApplyImportHelper = 1 << 26, // Indicates the node should never be wrapped with an import star helper (because, for example, it imports tslib itself)
67296729
/*@internal*/ IgnoreSourceNewlines = 1 << 27, // Overrides `printerOptions.preserveSourceNewlines` to print this node (and all descendants) with default whitespace.
67306730
/*@internal*/ Immutable = 1 << 28, // Indicates a node is a singleton intended to be reused in multiple locations. Any attempt to make further changes to the node will result in an error.
6731+
/*@internal*/ IndirectCall = 1 << 29, // Emit CallExpression as an indirect call: `(0, f)()`
67316732
}
67326733

67336734
export interface EmitHelperBase {

tests/baselines/reference/allowJscheckJsTypeParameterNoCrash.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ exports.__esModule = true;
3030
exports.a = void 0;
3131
var func_1 = require("./func");
3232
// hover on vextend
33-
exports.a = func_1.vextend({
33+
exports.a = (0, func_1.vextend)({
3434
watch: {
3535
data1: function (val) {
3636
this.data2 = 1;

tests/baselines/reference/allowSyntheticDefaultImportsCanPaintCrossModuleDeclaration.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ exports.__esModule = true;
2323
exports.__esModule = true;
2424
exports.A = void 0;
2525
var file1_1 = require("./file1");
26-
exports.A = file1_1.styled();
26+
exports.A = (0, file1_1.styled)();
2727

2828

2929
//// [color.d.ts]

tests/baselines/reference/ambientDeclarationsPatterns.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ foo(fileText);
3737
exports.__esModule = true;
3838
///<reference path="declarations.d.ts" />
3939
var foobarbaz_1 = require("foobarbaz");
40-
foobarbaz_1.foo(foobarbaz_1.baz);
40+
(0, foobarbaz_1.foo)(foobarbaz_1.baz);
4141
var foosball_1 = require("foosball");
42-
foobarbaz_1.foo(foosball_1.foos);
42+
(0, foobarbaz_1.foo)(foosball_1.foos);
4343
// Works with relative file name
4444
var file_text_1 = require("./file!text");
45-
foobarbaz_1.foo(file_text_1["default"]);
45+
(0, foobarbaz_1.foo)(file_text_1["default"]);

tests/baselines/reference/ambientShorthand.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ exports.__esModule = true;
2020
var jquery_1 = require("jquery");
2121
var baz = require("fs");
2222
var boom = require("jquery");
23-
jquery_1["default"](jquery_1.bar, baz, boom);
23+
(0, jquery_1["default"])(jquery_1.bar, baz, boom);

tests/baselines/reference/ambientShorthand_reExport.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ exports.__esModule = true;
4949
var reExportX_1 = require("./reExportX");
5050
var $ = require("./reExportAll");
5151
// '$' is not callable, it is an object.
52-
reExportX_1.x($);
52+
(0, reExportX_1.x)($);

tests/baselines/reference/amdDeclarationEmitNoExtraDeclare.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ define("Class", ["require", "exports", "Configurable"], function (require, expor
7272
return _super !== null && _super.apply(this, arguments) || this;
7373
}
7474
return ActualClass;
75-
}(Configurable_1.Configurable(HiddenClass)));
75+
}((0, Configurable_1.Configurable)(HiddenClass)));
7676
exports.ActualClass = ActualClass;
7777
});
7878

tests/baselines/reference/anonClassDeclarationEmitIsAnon.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ var __extends = (this && this.__extends) || (function () {
9696
exports.__esModule = true;
9797
exports.TimestampedUser = exports.User = void 0;
9898
var wrapClass_1 = require("./wrapClass");
99-
exports["default"] = wrapClass_1.wrapClass(0);
99+
exports["default"] = (0, wrapClass_1.wrapClass)(0);
100100
// Simple class
101101
var User = /** @class */ (function () {
102102
function User() {
@@ -112,7 +112,7 @@ var TimestampedUser = /** @class */ (function (_super) {
112112
return _super.call(this) || this;
113113
}
114114
return TimestampedUser;
115-
}(wrapClass_1.Timestamped(User)));
115+
}((0, wrapClass_1.Timestamped)(User)));
116116
exports.TimestampedUser = TimestampedUser;
117117

118118

tests/baselines/reference/callbackTagVariadicType.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ exports.x = void 0;
2222
/** @type {Foo} */
2323
var x = function () { return 1; };
2424
exports.x = x;
25-
var res = exports.x('a', 'b');
25+
var res = (0, exports.x)('a', 'b');
2626

2727

2828
//// [callbackTagVariadicType.d.ts]

tests/baselines/reference/commentsOnJSXExpressionsArePreserved(jsx=react-jsx,module=commonjs).js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ var Component = /** @class */ (function () {
2525
function Component() {
2626
}
2727
Component.prototype.render = function () {
28-
return _a.jsx("div", { children: null /* preserved */ }, void 0);
28+
return (0, _a.jsx)("div", { children: null /* preserved */ }, void 0);
2929
};
3030
return Component;
3131
}());

tests/baselines/reference/commentsOnJSXExpressionsArePreserved(jsx=react-jsxdev,module=commonjs).js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var Component = /** @class */ (function () {
2626
function Component() {
2727
}
2828
Component.prototype.render = function () {
29-
return _a.jsxDEV("div", { children: null /* preserved */ }, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 15 }, this);
29+
return (0, _a.jsxDEV)("div", { children: null /* preserved */ }, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 15 }, this);
3030
};
3131
return Component;
3232
}());

tests/baselines/reference/commonjsSafeImport.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ exports.Foo = Foo;
1919
"use strict";
2020
Object.defineProperty(exports, "__esModule", { value: true });
2121
var _10_lib_1 = require("./10_lib");
22-
_10_lib_1.Foo();
22+
(0, _10_lib_1.Foo)();
2323

2424

2525
//// [10_lib.d.ts]

tests/baselines/reference/declarationEmitCommonJsModuleReferencedType.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ exports.__esModule = true;
3030
exports.y = exports.x = void 0;
3131
var foo_1 = require("foo");
3232
var root_1 = require("root");
33-
exports.x = foo_1.foo();
34-
exports.y = root_1.bar();
33+
exports.x = (0, foo_1.foo)();
34+
exports.y = (0, root_1.bar)();

tests/baselines/reference/declarationEmitExpandoPropertyPrivateName.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ exports.q = void 0;
2323
var a_1 = require("./a");
2424
function q() { }
2525
exports.q = q;
26-
q.val = a_1.f();
26+
q.val = (0, a_1.f)();
2727

2828

2929
//// [a.d.ts]

tests/baselines/reference/declarationEmitExpandoWithGenericConstraint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var Point = function (x, y) { return ({ x: x, y: y }); };
2222
exports.Point = Point;
2323
var Rect = function (a, b) { return ({ a: a, b: b }); };
2424
exports.Rect = Rect;
25-
exports.Point.zero = function () { return exports.Point(0, 0); };
25+
exports.Point.zero = function () { return (0, exports.Point)(0, 0); };
2626

2727

2828
//// [declarationEmitExpandoWithGenericConstraint.d.ts]

tests/baselines/reference/declarationEmitExportAssignedNamespaceNoTripleSlashTypesReference.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ var get_comp_1 = require("./get-comp");
5353
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
5454
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
5555
exports.obj = {
56-
comp: get_comp_1.getComp()
56+
comp: (0, get_comp_1.getComp)()
5757
};
5858
//// [some-other-file.js]
5959
"use strict";

tests/baselines/reference/declarationEmitExportDeclaration.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
2626
exports.bar = void 0;
2727
var utils_1 = require("./utils");
2828
Object.defineProperty(exports, "bar", { enumerable: true, get: function () { return utils_1.bar; } });
29-
utils_1.foo();
29+
(0, utils_1.foo)();
3030
var obj;
3131

3232

tests/baselines/reference/declarationEmitForGlobalishSpecifierSymlink.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const a: import("typescript-fsa").A;
3939
exports.__esModule = true;
4040
exports.a = void 0;
4141
var typescript_fsa_1 = require("typescript-fsa");
42-
exports.a = typescript_fsa_1.getA();
42+
exports.a = (0, typescript_fsa_1.getA)();
4343

4444

4545
//// [index.d.ts]

tests/baselines/reference/declarationEmitForGlobalishSpecifierSymlink2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const a: import("typescript-fsa").A;
2727
exports.__esModule = true;
2828
exports.a = void 0;
2929
var typescript_fsa_1 = require("typescript-fsa");
30-
exports.a = typescript_fsa_1.getA();
30+
exports.a = (0, typescript_fsa_1.getA)();
3131

3232

3333
//// [index.d.ts]

tests/baselines/reference/declarationEmitForModuleImportingModuleAugmentationRetainsImport.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ var ParentThing = /** @class */ (function () {
3131
return ParentThing;
3232
}());
3333
exports.ParentThing = ParentThing;
34-
child1_1.child1(ParentThing.prototype);
34+
(0, child1_1.child1)(ParentThing.prototype);
3535
//// [child1.js]
3636
"use strict";
3737
exports.__esModule = true;

tests/baselines/reference/declarationEmitForTypesWhichNeedImportTypes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ exports.createNamed = createNamed;
2525
exports.__esModule = true;
2626
exports.Value = void 0;
2727
var b_1 = require("./b");
28-
exports.Value = b_1.createNamed();
28+
exports.Value = (0, b_1.createNamed)();
2929

3030

3131
//// [b.d.ts]

tests/baselines/reference/declarationEmitPathMappingMonorepo.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ exports.__esModule = true;
2121
exports.b = void 0;
2222
var a_1 = require("@ts-bug/a");
2323
function b(text) {
24-
return a_1.a(text);
24+
return (0, a_1.a)(text);
2525
}
2626
exports.b = b;
2727

tests/baselines/reference/declarationEmitPathMappingMonorepo2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default createSvgIcon("Hello", "ArrowLeft");
3333
"use strict";
3434
exports.__esModule = true;
3535
var utils_1 = require("@ts-bug/core/utils");
36-
exports["default"] = utils_1.createSvgIcon("Hello", "ArrowLeft");
36+
exports["default"] = (0, utils_1.createSvgIcon)("Hello", "ArrowLeft");
3737

3838

3939
//// [index.d.ts]

tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3333
var scalar_1 = require("../lib/operators/scalar");
3434
exports.default = {
3535
get xs() {
36-
return scalar_1.scalar("14px");
36+
return (0, scalar_1.scalar)("14px");
3737
}
3838
};
3939

tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ define("settings/spacing", ["require", "exports", "lib/operators/scalar"], funct
3434
Object.defineProperty(exports, "__esModule", { value: true });
3535
exports.default = {
3636
get xs() {
37-
return scalar_1.scalar("14px");
37+
return (0, scalar_1.scalar)("14px");
3838
}
3939
};
4040
});

tests/baselines/reference/declarationEmitQualifiedAliasTypeArgument.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ export const fun2 = create<Q>();
3232
exports.__esModule = true;
3333
exports.fun2 = exports.fun = void 0;
3434
var bbb_1 = require("./bbb");
35-
exports.fun = bbb_1.create();
36-
exports.fun2 = bbb_1.create();
35+
exports.fun = (0, bbb_1.create)();
36+
exports.fun2 = (0, bbb_1.create)();
3737

3838

3939
//// [index.d.ts]

tests/baselines/reference/declarationEmitReadonlyComputedProperty.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ var __assign = (this && this.__assign) || function () {
4848
exports.__esModule = true;
4949
exports.spread = void 0;
5050
var bug_1 = require("./bug");
51-
exports.spread = __assign({}, bug_1.createInstance());
51+
exports.spread = __assign({}, (0, bug_1.createInstance)());
5252

5353

5454
//// [bug.d.ts]

tests/baselines/reference/declarationEmitSymlinkPaths.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3838
exports.NotificationScenario = void 0;
3939
var index_1 = require("search/lib/index");
4040
var NotificationAPIUtils_1 = require("../API/NotificationAPIUtils");
41-
exports.NotificationScenario = index_1.test(NotificationAPIUtils_1.getNotification);
41+
exports.NotificationScenario = (0, index_1.test)(NotificationAPIUtils_1.getNotification);
4242

4343

4444
//// [NotificationAPIUtils.d.ts]

tests/baselines/reference/declarationsForInferredTypeFromOtherFile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ exports.__esModule = true;
3737
exports.bar = void 0;
3838
var file2_1 = require("./file2");
3939
function bar() {
40-
return file2_1.foo();
40+
return (0, file2_1.foo)();
4141
}
4242
exports.bar = bar;
4343

tests/baselines/reference/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ var testRecFun = function (parent) {
7575
return {
7676
result: parent,
7777
deeper: function (child) {
78-
return exports.testRecFun(__assign(__assign({}, parent), child));
78+
return (0, exports.testRecFun)(__assign(__assign({}, parent), child));
7979
}
8080
};
8181
};
8282
exports.testRecFun = testRecFun;
83-
var p1 = exports.testRecFun({ one: '1' });
83+
var p1 = (0, exports.testRecFun)({ one: '1' });
8484
void p1.result.one;
8585
var p2 = p1.deeper({ two: '2' });
8686
void p2.result.one;

0 commit comments

Comments
 (0)