From 285497edf804af2959df41bdaa689d76588e043a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 13 Mar 2015 16:45:58 -0700 Subject: [PATCH] Reserve _i and _n as names we often want to generate --- src/compiler/emitter.ts | 39 +++++++++------- ...gedTemplateStringsTypeArgumentInference.js | 44 +++++++++---------- ...dTemplateStringsWithOverloadResolution3.js | 22 +++++----- 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 230b5eac310..51b74436673 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2116,16 +2116,23 @@ module ts { // Create a temporary variable with a unique unused name. The forLoopVariable parameter signals that the // name should be one that is appropriate for a for loop variable. - function createTempVariable(location: Node, forLoopVariable?: boolean): Identifier { - let name = forLoopVariable ? "_i" : undefined; - while (true) { - if (name && !isExistingName(location, name)) { - break; - } + function createTempVariable(location: Node, preferredName?: string): Identifier { + let name = preferredName; + for ( ; !name || isExistingName(location, name); tempCount++) { // _a .. _h, _j ... _z, _0, _1, ... - // Note that _i is skipped - name = "_" + (tempCount < 25 ? String.fromCharCode(tempCount + (tempCount < 8 ? 0 : 1) + CharacterCodes.a) : tempCount - 25); - tempCount++; + + // Note: we avoid generating _i and _n as those are common names we want in other places. + var char = CharacterCodes.a + tempCount; + if (char === CharacterCodes.i || char === CharacterCodes.n) { + continue; + } + + if (tempCount < 26) { + name = "_" + String.fromCharCode(char); + } + else { + name = "_" + (tempCount - 26); + } } // This is necessary so that a name generated via renameNonTopLevelLetAndConst will see the name @@ -2144,8 +2151,8 @@ module ts { tempVariables.push(name); } - function createAndRecordTempVariable(location: Node): Identifier { - let temp = createTempVariable(location, /*forLoopVariable*/ false); + function createAndRecordTempVariable(location: Node, preferredName?: string): Identifier { + let temp = createTempVariable(location, preferredName); recordTempDeclaration(temp); return temp; @@ -3580,10 +3587,10 @@ module ts { // // we don't want to emit a temporary variable for the RHS, just use it directly. let rhsIsIdentifier = node.expression.kind === SyntaxKind.Identifier; - let counter = createTempVariable(node, /*forLoopVariable*/ true); - let rhsReference = rhsIsIdentifier ? node.expression : createTempVariable(node, /*forLoopVariable*/ false); + let counter = createTempVariable(node, /*preferredName*/ "_i"); + let rhsReference = rhsIsIdentifier ? node.expression : createTempVariable(node); - var cachedLength = compilerOptions.cacheDownlevelForOfLength ? createTempVariable(node, /*forLoopVariable:*/ false) : undefined; + var cachedLength = compilerOptions.cacheDownlevelForOfLength ? createTempVariable(node, /*preferredName:*/ "_n") : undefined; // This is the let keyword for the counter and rhsReference. The let keyword for // the LHS will be emitted inside the body. @@ -3668,7 +3675,7 @@ module ts { else { // It's an empty declaration list. This can only happen in an error case, if the user wrote // for (let of []) {} - emitNodeWithoutSourceMap(createTempVariable(node, /*forLoopVariable*/ false)); + emitNodeWithoutSourceMap(createTempVariable(node)); write(" = "); emitNodeWithoutSourceMap(rhsIterationValue); } @@ -4251,7 +4258,7 @@ module ts { if (languageVersion < ScriptTarget.ES6 && hasRestParameters(node)) { let restIndex = node.parameters.length - 1; let restParam = node.parameters[restIndex]; - let tempName = createTempVariable(node, /*forLoopVariable*/ true).text; + let tempName = createTempVariable(node, /*preferredName:*/ "_i").text; writeLine(); emitLeadingComments(restParam); emitStart(restParam); diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.js b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.js index 663969caefc..5b128221aa6 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.js +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.js @@ -145,23 +145,16 @@ function someGenerics4(strs, n, f) { // 2 parameter generic tag with argument 2 of type parameter type and argument 1 of function type whose parameter is of type parameter type function someGenerics5(strs, n, f) { } -(_n = ["", " ", ""], _n.raw = ["", " ", ""], someGenerics5(_n, 4, function () { +(_o = ["", " ", ""], _o.raw = ["", " ", ""], someGenerics5(_o, 4, function () { return null; })); -(_o = ["", "", ""], _o.raw = ["", "", ""], someGenerics5(_o, '', function () { +(_p = ["", "", ""], _p.raw = ["", "", ""], someGenerics5(_p, '', function () { return 3; })); -(_p = ["", "", ""], _p.raw = ["", "", ""], someGenerics5(_p, null, null)); +(_q = ["", "", ""], _q.raw = ["", "", ""], someGenerics5(_q, null, null)); // Generic tag with multiple arguments of function types that each have parameters of the same generic type function someGenerics6(strs, a, b, c) { } -(_q = ["", "", "", ""], _q.raw = ["", "", "", ""], someGenerics6(_q, function (n) { - return n; -}, function (n) { - return n; -}, function (n) { - return n; -})); (_r = ["", "", "", ""], _r.raw = ["", "", "", ""], someGenerics6(_r, function (n) { return n; }, function (n) { @@ -176,16 +169,16 @@ function someGenerics6(strs, a, b, c) { }, function (n) { return n; })); -// Generic tag with multiple arguments of function types that each have parameters of different generic type -function someGenerics7(strs, a, b, c) { -} -(_t = ["", "", "", ""], _t.raw = ["", "", "", ""], someGenerics7(_t, function (n) { +(_t = ["", "", "", ""], _t.raw = ["", "", "", ""], someGenerics6(_t, function (n) { return n; }, function (n) { return n; }, function (n) { return n; })); +// Generic tag with multiple arguments of function types that each have parameters of different generic type +function someGenerics7(strs, a, b, c) { +} (_u = ["", "", "", ""], _u.raw = ["", "", "", ""], someGenerics7(_u, function (n) { return n; }, function (n) { @@ -200,19 +193,26 @@ function someGenerics7(strs, a, b, c) { }, function (n) { return n; })); +(_w = ["", "", "", ""], _w.raw = ["", "", "", ""], someGenerics7(_w, function (n) { + return n; +}, function (n) { + return n; +}, function (n) { + return n; +})); // Generic tag with argument of generic function type function someGenerics8(strs, n) { return n; } -var x = (_w = ["", ""], _w.raw = ["", ""], someGenerics8(_w, someGenerics7)); -(_x = ["", "", "", ""], _x.raw = ["", "", "", ""], x(_x, null, null, null)); +var x = (_x = ["", ""], _x.raw = ["", ""], someGenerics8(_x, someGenerics7)); +(_y = ["", "", "", ""], _y.raw = ["", "", "", ""], x(_y, null, null, null)); // Generic tag with multiple parameters of generic type passed arguments with no best common type function someGenerics9(strs, a, b, c) { return null; } -var a9a = (_y = ["", "", "", ""], _y.raw = ["", "", "", ""], someGenerics9(_y, '', 0, [])); +var a9a = (_z = ["", "", "", ""], _z.raw = ["", "", "", ""], someGenerics9(_z, '', 0, [])); var a9a; -var a9e = (_z = ["", "", "", ""], _z.raw = ["", "", "", ""], someGenerics9(_z, undefined, { +var a9e = (_0 = ["", "", "", ""], _0.raw = ["", "", "", ""], someGenerics9(_0, undefined, { x: 6, z: new Date() }, { @@ -221,7 +221,7 @@ var a9e = (_z = ["", "", "", ""], _z.raw = ["", "", "", ""], someGenerics9(_z, u })); var a9e; // Generic tag with multiple parameters of generic type passed arguments with a single best common type -var a9d = (_0 = ["", "", "", ""], _0.raw = ["", "", "", ""], someGenerics9(_0, { +var a9d = (_1 = ["", "", "", ""], _1.raw = ["", "", "", ""], someGenerics9(_1, { x: 3 }, { x: 6 @@ -231,9 +231,9 @@ var a9d = (_0 = ["", "", "", ""], _0.raw = ["", "", "", ""], someGenerics9(_0, { var a9d; // Generic tag with multiple parameters of generic type where one argument is of type 'any' var anyVar; -var a = (_1 = ["", "", "", ""], _1.raw = ["", "", "", ""], someGenerics9(_1, 7, anyVar, 4)); +var a = (_2 = ["", "", "", ""], _2.raw = ["", "", "", ""], someGenerics9(_2, 7, anyVar, 4)); var a; // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' -var arr = (_2 = ["", "", "", ""], _2.raw = ["", "", "", ""], someGenerics9(_2, [], null, undefined)); +var arr = (_3 = ["", "", "", ""], _3.raw = ["", "", "", ""], someGenerics9(_3, [], null, undefined)); var arr; -var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2; +var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3; diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.js b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.js index 1840fed234b..24b0b16ea35 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.js +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.js @@ -103,26 +103,26 @@ var s = (_k = ["", ""], _k.raw = ["", ""], fn3(_k, 4)); var s = (_l = ["", "", "", ""], _l.raw = ["", "", "", ""], fn3(_l, '', '', '')); var n = (_m = ["", "", "", ""], _m.raw = ["", "", "", ""], fn3(_m, '', '', 3)); // Generic overloads with differing arity tagging with argument count that doesn't match any overload -(_n = [""], _n.raw = [""], fn3(_n)); // Error +(_o = [""], _o.raw = [""], fn3(_o)); // Error function fn4() { } // Generic overloads with constraints tagged with types that satisfy the constraints -(_o = ["", "", ""], _o.raw = ["", "", ""], fn4(_o, '', 3)); -(_p = ["", "", ""], _p.raw = ["", "", ""], fn4(_p, 3, '')); -(_q = ["", "", ""], _q.raw = ["", "", ""], fn4(_q, 3, undefined)); -(_r = ["", "", ""], _r.raw = ["", "", ""], fn4(_r, '', null)); +(_p = ["", "", ""], _p.raw = ["", "", ""], fn4(_p, '', 3)); +(_q = ["", "", ""], _q.raw = ["", "", ""], fn4(_q, 3, '')); +(_r = ["", "", ""], _r.raw = ["", "", ""], fn4(_r, 3, undefined)); +(_s = ["", "", ""], _s.raw = ["", "", ""], fn4(_s, '', null)); // Generic overloads with constraints called with type arguments that do not satisfy the constraints -(_s = ["", "", ""], _s.raw = ["", "", ""], fn4(_s, null, null)); // Error +(_t = ["", "", ""], _t.raw = ["", "", ""], fn4(_t, null, null)); // Error // Generic overloads with constraints called without type arguments but with types that do not satisfy the constraints -(_t = ["", "", ""], _t.raw = ["", "", ""], fn4(_t, true, null)); -(_u = ["", "", ""], _u.raw = ["", "", ""], fn4(_u, null, true)); +(_u = ["", "", ""], _u.raw = ["", "", ""], fn4(_u, true, null)); +(_v = ["", "", ""], _v.raw = ["", "", ""], fn4(_v, null, true)); function fn5() { return undefined; } -(_v = ["", ""], _v.raw = ["", ""], fn5(_v, function (n) { +(_w = ["", ""], _w.raw = ["", ""], fn5(_w, function (n) { return n.toFixed(); })); // will error; 'n' should have type 'string'. -(_w = ["", ""], _w.raw = ["", ""], fn5(_w, function (n) { +(_x = ["", ""], _x.raw = ["", ""], fn5(_x, function (n) { return n.substr(0); })); -var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w; +var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;