Skip to content

Commit 2cf1260

Browse files
committed
Check function body for the unique name
1 parent 91edd77 commit 2cf1260

File tree

5 files changed

+43
-7
lines changed

5 files changed

+43
-7
lines changed

src/compiler/transformers/es2015.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ namespace ts {
424424
return visitFunctionDeclaration(node as FunctionDeclaration);
425425

426426
case SyntaxKind.ArrowFunction:
427-
let name: string | undefined = undefined;
427+
let name: string | undefined;
428428
if (node.parent && isVariableDeclaration(node.parent) && isIdentifier(node.parent.name)) {
429429
name = `${node.parent.name.escapedText}`;
430430
}
@@ -1786,7 +1786,7 @@ namespace ts {
17861786
const func = factory.createFunctionExpression(
17871787
/*modifiers*/ undefined,
17881788
/*asteriskToken*/ undefined,
1789-
/*name*/ name,
1789+
/*name*/ name ? createNonCollidingName(name, node) : undefined,
17901790
/*typeParameters*/ undefined,
17911791
visitParameterList(node.parameters, visitor, context),
17921792
/*type*/ undefined,
@@ -4421,4 +4421,40 @@ namespace ts {
44214421
return isIdentifier(expression) && expression.escapedText === "arguments";
44224422
}
44234423
}
4424+
4425+
function forEachFreeIdentifier(node: Node, cb: (id: Identifier) => void): void {
4426+
if (isIdentifier(node) && isFreeIdentifier(node)) cb(node);
4427+
forEachChild(node, child => forEachFreeIdentifier(child, cb));
4428+
}
4429+
4430+
function isFreeIdentifier(node: Identifier): boolean {
4431+
const { parent } = node;
4432+
switch (parent.kind) {
4433+
case SyntaxKind.PropertyAccessExpression:
4434+
return (parent as PropertyAccessExpression).name !== node;
4435+
case SyntaxKind.BindingElement:
4436+
return (parent as BindingElement).propertyName !== node;
4437+
case SyntaxKind.ImportSpecifier:
4438+
return (parent as ImportSpecifier).propertyName !== node;
4439+
default:
4440+
return true;
4441+
}
4442+
}
4443+
4444+
function createNonCollidingName(name: string, node: Node): string {
4445+
const identifiers = new Set<string>()
4446+
forEachFreeIdentifier(node, (identifier) => {
4447+
identifiers.add(`${identifier.escapedText}`)
4448+
})
4449+
4450+
return createUniqueName(name, 0, identifiers)
4451+
}
4452+
4453+
function createUniqueName(name: string, counter: number, existingNames: Set<string>): string {
4454+
const fullName = counter === 0 ? name : `${name}_${counter}`
4455+
if (!existingNames.has(fullName)) {
4456+
return fullName
4457+
}
4458+
return createUniqueName(name, counter + 1, existingNames)
4459+
}
44244460
}

tests/baselines/reference/declFileTypeofFunction.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ var foo2 = foo;
4747
var foo3 = function () {
4848
return foo3;
4949
};
50-
var x = function x() {
50+
var x = function x_1() {
5151
return x;
5252
};
5353
function foo5(x) {

tests/baselines/reference/functionExpressionContextualTyping1.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ var Class = /** @class */ (function () {
7676
Class.prototype.foo = function () { };
7777
return Class;
7878
}());
79-
var a1 = function a1(a1) {
79+
var a1 = function a1_1(a1) {
8080
a1.foo();
8181
return 1;
8282
};
@@ -112,7 +112,7 @@ b6 = function (i) {
112112
b7 = function (j, m) { }; // Per spec, no contextual signature can be extracted in this case. (Otherwise clause)
113113
var C = /** @class */ (function () {
114114
function C() {
115-
var k = function k(j, k) {
115+
var k = function k_1(j, k) {
116116
return [j, k];
117117
}; // Per spec, no contextual signature can be extracted in this case.
118118
}

tests/baselines/reference/implicitAnyFromCircularInference.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ var f1 = function () {
6565
return f1();
6666
};
6767
// Error expected
68-
var f2 = function f2() { return f2(); };
68+
var f2 = function f2_1() { return f2(); };
6969
// Error expected
7070
function h() {
7171
return foo();

tests/baselines/reference/templateStringInArrowFunction.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
var x = x => `abc${ x }def`;
33

44
//// [templateStringInArrowFunction.js]
5-
var x = function x(x) { return "abc" + x + "def"; };
5+
var x = function x_1(x) { return "abc" + x + "def"; };

0 commit comments

Comments
 (0)