Skip to content

Commit

Permalink
Indirect calls for imported functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuckton committed Jun 17, 2021
1 parent 5be0d71 commit f0a7f99
Show file tree
Hide file tree
Showing 175 changed files with 10,922 additions and 333 deletions.
10,571 changes: 10,547 additions & 24 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2473,7 +2473,17 @@ namespace ts {
}

function emitCallExpression(node: CallExpression) {
const indirectCall = getEmitFlags(node) & EmitFlags.IndirectCall;
if (indirectCall) {
writePunctuation("(");
writeLiteral("0");
writePunctuation(",");
writeSpace();
}
emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess);
if (indirectCall) {
writePunctuation(")");
}
emit(node.questionDotToken);
emitTypeArguments(node, node.typeArguments);
emitExpressionList(node, node.arguments, ListFormat.CallExpressionArguments, parenthesizer.parenthesizeExpressionForDisallowedComma);
Expand All @@ -2488,7 +2498,17 @@ namespace ts {
}

function emitTaggedTemplateExpression(node: TaggedTemplateExpression) {
const indirectCall = getEmitFlags(node) & EmitFlags.IndirectCall;
if (indirectCall) {
writePunctuation("(");
writeLiteral("0");
writePunctuation(",");
writeSpace();
}
emitExpression(node.tag, parenthesizer.parenthesizeLeftSideOfAccess);
if (indirectCall) {
writePunctuation(")");
}
emitTypeArguments(node, node.typeArguments);
writeSpace();
emitExpression(node.template);
Expand Down
45 changes: 45 additions & 0 deletions src/compiler/transformers/module/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ namespace ts {
const previousOnEmitNode = context.onEmitNode;
context.onSubstituteNode = onSubstituteNode;
context.onEmitNode = onEmitNode;
context.enableSubstitution(SyntaxKind.CallExpression); // Substitute calls to imported/exported symbols to avoid incorrect `this`.
context.enableSubstitution(SyntaxKind.TaggedTemplateExpression); // Substitute calls to imported/exported symbols to avoid incorrect `this`.
context.enableSubstitution(SyntaxKind.Identifier); // Substitutes expression identifiers with imported/exported symbols.
context.enableSubstitution(SyntaxKind.BinaryExpression); // Substitutes assignments to exported symbols.
context.enableSubstitution(SyntaxKind.PrefixUnaryExpression); // Substitutes updates to exported symbols.
Expand All @@ -47,6 +49,8 @@ namespace ts {
let currentModuleInfo: ExternalModuleInfo; // The ExternalModuleInfo for the current file.
let noSubstitution: boolean[]; // Set of nodes for which substitution rules should be ignored.
let needUMDDynamicImportHelper: boolean;
const zeroLiteral = factory.createNumericLiteral(0);
setEmitFlags(zeroLiteral, EmitFlags.Immutable);

return chainBundle(context, transformSourceFile);

Expand Down Expand Up @@ -1741,6 +1745,10 @@ namespace ts {
switch (node.kind) {
case SyntaxKind.Identifier:
return substituteExpressionIdentifier(node as Identifier);
case SyntaxKind.CallExpression:
return substituteCallExpression(node as CallExpression);
case SyntaxKind.TaggedTemplateExpression:
return substituteTaggedTemplateExpression(node as TaggedTemplateExpression);
case SyntaxKind.BinaryExpression:
return substituteBinaryExpression(node as BinaryExpression);
case SyntaxKind.PostfixUnaryExpression:
Expand All @@ -1751,6 +1759,43 @@ namespace ts {
return node;
}

function substituteCallExpression(node: CallExpression) {
if (isIdentifier(node.expression)) {
const expression = substituteExpressionIdentifier(node.expression);
noSubstitution[getNodeId(expression)] = true;
if (!isIdentifier(expression)) {
return addEmitFlags(
factory.updateCallExpression(node,
expression,
/*typeArguments*/ undefined,
node.arguments
),
EmitFlags.IndirectCall
);

}
}
return node;
}

function substituteTaggedTemplateExpression(node: TaggedTemplateExpression) {
if (isIdentifier(node.tag)) {
const tag = substituteExpressionIdentifier(node.tag);
noSubstitution[getNodeId(tag)] = true;
if (!isIdentifier(tag)) {
return addEmitFlags(
factory.updateTaggedTemplateExpression(node,
tag,
/*typeArguments*/ undefined,
node.template
),
EmitFlags.IndirectCall
);
}
}
return node;
}

/**
* Substitution for an Identifier expression that may contain an imported or exported
* symbol.
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6728,6 +6728,7 @@ namespace ts {
/*@internal*/ NeverApplyImportHelper = 1 << 26, // Indicates the node should never be wrapped with an import star helper (because, for example, it imports tslib itself)
/*@internal*/ IgnoreSourceNewlines = 1 << 27, // Overrides `printerOptions.preserveSourceNewlines` to print this node (and all descendants) with default whitespace.
/*@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.
/*@internal*/ IndirectCall = 1 << 29, // Emit CallExpression as an indirect call: `(0, f)()`
}

export interface EmitHelperBase {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ exports.__esModule = true;
exports.a = void 0;
var func_1 = require("./func");
// hover on vextend
exports.a = func_1.vextend({
exports.a = (0, func_1.vextend)({
watch: {
data1: function (val) {
this.data2 = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ exports.__esModule = true;
exports.__esModule = true;
exports.A = void 0;
var file1_1 = require("./file1");
exports.A = file1_1.styled();
exports.A = (0, file1_1.styled)();


//// [color.d.ts]
Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/ambientDeclarationsPatterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ foo(fileText);
exports.__esModule = true;
///<reference path="declarations.d.ts" />
var foobarbaz_1 = require("foobarbaz");
foobarbaz_1.foo(foobarbaz_1.baz);
(0, foobarbaz_1.foo)(foobarbaz_1.baz);
var foosball_1 = require("foosball");
foobarbaz_1.foo(foosball_1.foos);
(0, foobarbaz_1.foo)(foosball_1.foos);
// Works with relative file name
var file_text_1 = require("./file!text");
foobarbaz_1.foo(file_text_1["default"]);
(0, foobarbaz_1.foo)(file_text_1["default"]);
2 changes: 1 addition & 1 deletion tests/baselines/reference/ambientShorthand.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ exports.__esModule = true;
var jquery_1 = require("jquery");
var baz = require("fs");
var boom = require("jquery");
jquery_1["default"](jquery_1.bar, baz, boom);
(0, jquery_1["default"])(jquery_1.bar, baz, boom);
2 changes: 1 addition & 1 deletion tests/baselines/reference/ambientShorthand_reExport.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ exports.__esModule = true;
var reExportX_1 = require("./reExportX");
var $ = require("./reExportAll");
// '$' is not callable, it is an object.
reExportX_1.x($);
(0, reExportX_1.x)($);
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ define("Class", ["require", "exports", "Configurable"], function (require, expor
return _super !== null && _super.apply(this, arguments) || this;
}
return ActualClass;
}(Configurable_1.Configurable(HiddenClass)));
}((0, Configurable_1.Configurable)(HiddenClass)));
exports.ActualClass = ActualClass;
});

Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/anonClassDeclarationEmitIsAnon.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ var __extends = (this && this.__extends) || (function () {
exports.__esModule = true;
exports.TimestampedUser = exports.User = void 0;
var wrapClass_1 = require("./wrapClass");
exports["default"] = wrapClass_1.wrapClass(0);
exports["default"] = (0, wrapClass_1.wrapClass)(0);
// Simple class
var User = /** @class */ (function () {
function User() {
Expand All @@ -112,7 +112,7 @@ var TimestampedUser = /** @class */ (function (_super) {
return _super.call(this) || this;
}
return TimestampedUser;
}(wrapClass_1.Timestamped(User)));
}((0, wrapClass_1.Timestamped)(User)));
exports.TimestampedUser = TimestampedUser;


Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/callbackTagVariadicType.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ exports.x = void 0;
/** @type {Foo} */
var x = function () { return 1; };
exports.x = x;
var res = exports.x('a', 'b');
var res = (0, exports.x)('a', 'b');


//// [callbackTagVariadicType.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var Component = /** @class */ (function () {
function Component() {
}
Component.prototype.render = function () {
return _a.jsx("div", { children: null /* preserved */ }, void 0);
return (0, _a.jsx)("div", { children: null /* preserved */ }, void 0);
};
return Component;
}());
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var Component = /** @class */ (function () {
function Component() {
}
Component.prototype.render = function () {
return _a.jsxDEV("div", { children: null /* preserved */ }, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 15 }, this);
return (0, _a.jsxDEV)("div", { children: null /* preserved */ }, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 15 }, this);
};
return Component;
}());
2 changes: 1 addition & 1 deletion tests/baselines/reference/commonjsSafeImport.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ exports.Foo = Foo;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _10_lib_1 = require("./10_lib");
_10_lib_1.Foo();
(0, _10_lib_1.Foo)();


//// [10_lib.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ exports.__esModule = true;
exports.y = exports.x = void 0;
var foo_1 = require("foo");
var root_1 = require("root");
exports.x = foo_1.foo();
exports.y = root_1.bar();
exports.x = (0, foo_1.foo)();
exports.y = (0, root_1.bar)();
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ exports.q = void 0;
var a_1 = require("./a");
function q() { }
exports.q = q;
q.val = a_1.f();
q.val = (0, a_1.f)();


//// [a.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ 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); };
exports.Point.zero = function () { return (0, exports.Point)(0, 0); };


//// [declarationEmitExpandoWithGenericConstraint.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var get_comp_1 = require("./get-comp");
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
exports.obj = {
comp: get_comp_1.getComp()
comp: (0, get_comp_1.getComp)()
};
//// [some-other-file.js]
"use strict";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.bar = void 0;
var utils_1 = require("./utils");
Object.defineProperty(exports, "bar", { enumerable: true, get: function () { return utils_1.bar; } });
utils_1.foo();
(0, utils_1.foo)();
var obj;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const a: import("typescript-fsa").A;
exports.__esModule = true;
exports.a = void 0;
var typescript_fsa_1 = require("typescript-fsa");
exports.a = typescript_fsa_1.getA();
exports.a = (0, typescript_fsa_1.getA)();


//// [index.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const a: import("typescript-fsa").A;
exports.__esModule = true;
exports.a = void 0;
var typescript_fsa_1 = require("typescript-fsa");
exports.a = typescript_fsa_1.getA();
exports.a = (0, typescript_fsa_1.getA)();


//// [index.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var ParentThing = /** @class */ (function () {
return ParentThing;
}());
exports.ParentThing = ParentThing;
child1_1.child1(ParentThing.prototype);
(0, child1_1.child1)(ParentThing.prototype);
//// [child1.js]
"use strict";
exports.__esModule = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ exports.createNamed = createNamed;
exports.__esModule = true;
exports.Value = void 0;
var b_1 = require("./b");
exports.Value = b_1.createNamed();
exports.Value = (0, b_1.createNamed)();


//// [b.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ exports.__esModule = true;
exports.b = void 0;
var a_1 = require("@ts-bug/a");
function b(text) {
return a_1.a(text);
return (0, a_1.a)(text);
}
exports.b = b;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default createSvgIcon("Hello", "ArrowLeft");
"use strict";
exports.__esModule = true;
var utils_1 = require("@ts-bug/core/utils");
exports["default"] = utils_1.createSvgIcon("Hello", "ArrowLeft");
exports["default"] = (0, utils_1.createSvgIcon)("Hello", "ArrowLeft");


//// [index.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
var scalar_1 = require("../lib/operators/scalar");
exports.default = {
get xs() {
return scalar_1.scalar("14px");
return (0, scalar_1.scalar)("14px");
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ define("settings/spacing", ["require", "exports", "lib/operators/scalar"], funct
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
get xs() {
return scalar_1.scalar("14px");
return (0, scalar_1.scalar)("14px");
}
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export const fun2 = create<Q>();
exports.__esModule = true;
exports.fun2 = exports.fun = void 0;
var bbb_1 = require("./bbb");
exports.fun = bbb_1.create();
exports.fun2 = bbb_1.create();
exports.fun = (0, bbb_1.create)();
exports.fun2 = (0, bbb_1.create)();


//// [index.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var __assign = (this && this.__assign) || function () {
exports.__esModule = true;
exports.spread = void 0;
var bug_1 = require("./bug");
exports.spread = __assign({}, bug_1.createInstance());
exports.spread = __assign({}, (0, bug_1.createInstance)());


//// [bug.d.ts]
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/declarationEmitSymlinkPaths.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.NotificationScenario = void 0;
var index_1 = require("search/lib/index");
var NotificationAPIUtils_1 = require("../API/NotificationAPIUtils");
exports.NotificationScenario = index_1.test(NotificationAPIUtils_1.getNotification);
exports.NotificationScenario = (0, index_1.test)(NotificationAPIUtils_1.getNotification);


//// [NotificationAPIUtils.d.ts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ exports.__esModule = true;
exports.bar = void 0;
var file2_1 = require("./file2");
function bar() {
return file2_1.foo();
return (0, file2_1.foo)();
}
exports.bar = bar;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ var testRecFun = function (parent) {
return {
result: parent,
deeper: function (child) {
return exports.testRecFun(__assign(__assign({}, parent), child));
return (0, exports.testRecFun)(__assign(__assign({}, parent), child));
}
};
};
exports.testRecFun = testRecFun;
var p1 = exports.testRecFun({ one: '1' });
var p1 = (0, exports.testRecFun)({ one: '1' });
void p1.result.one;
var p2 = p1.deeper({ two: '2' });
void p2.result.one;
Expand Down
Loading

0 comments on commit f0a7f99

Please sign in to comment.