Skip to content

Commit 0fdb207

Browse files
committed
addressed PR feedback
1 parent 141c96b commit 0fdb207

7 files changed

Lines changed: 171 additions & 110 deletions

File tree

src/compiler/emitter.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ module ts {
1919
return isExternalModule(sourceFile) || isDeclarationFile(sourceFile);
2020
}
2121

22+
// flag enum used to request and track usages of few dedicated temp variables
23+
// enum values are used to set/check bit values and thus should not have bit collisions.
2224
const enum TempVariableKind {
2325
auto = 0,
2426
_i = 1,
@@ -216,7 +218,7 @@ module ts {
216218
// _i;
217219
// }
218220
// we should be able to detect if let _i was shadowed by some temp variable that was allocated in scope
219-
function hasConflictsWithTempVariables(name: string): boolean {
221+
function nameConflictsWithSomeTempVariable(name: string): boolean {
220222
// temp variable names always start with '_'
221223
if (name.length < 2 || name.charCodeAt(0) !== CharacterCodes._) {
222224
return false;
@@ -242,7 +244,12 @@ module ts {
242244
}
243245
}
244246

247+
// This function generates a name using the following pattern:
245248
// _a .. _h, _j ... _z, _0, _1, ...
249+
// It is guaranteed that generated name will not shadow any existing user-defined names,
250+
// however it can hide another name generated by this function higher in the scope.
251+
// NOTE: names generated by 'makeTempVariableName' and 'makeUniqueName' will never conflict.
252+
// see comment for 'makeTempVariableName' for more information.
246253
function makeTempVariableName(location: Node, tempVariableKind: TempVariableKind): string {
247254
let tempName: string;
248255
if (tempVariableKind !== TempVariableKind.auto && !(predefinedTempsInUse & tempVariableKind)) {
@@ -272,8 +279,17 @@ module ts {
272279
return tempName;
273280
}
274281

275-
// unique names always end with _<number>
276-
// generated unique names: name_1, name_2...
282+
// Generates a name that is unique within current file and does not collide with
283+
// any names in global scope.
284+
// NOTE: names generated by 'makeTempVariableName' and 'makeUniqueName' will never conflict
285+
// because of the way how these names are generated
286+
// - makeUniqueName builds a name by picking a base name (which should not be empty string)
287+
// and appending suffix '_<number>'
288+
// - makeTempVariableName creates a name using the following pattern:
289+
// _a .. _h, _j ... _z, _0, _1, ...
290+
// This means that names from 'makeTempVariableName' will have only one underscore at the beginning
291+
// and names from 'makeUniqieName' will have at least one underscore in the middle
292+
// so they will never collide.
277293
function makeUniqueName(baseName: string): string {
278294
Debug.assert(!!baseName);
279295

@@ -2787,8 +2803,9 @@ module ts {
27872803
let list = getAncestor(node, SyntaxKind.VariableDeclarationList);
27882804
if (list.parent.kind === SyntaxKind.VariableStatement) {
27892805
let isSourceFileLevelBinding = list.parent.parent.kind === SyntaxKind.SourceFile;
2790-
let isModuleLevelBinding = list.parent.parent.kind === SyntaxKind.ModuleDeclaration;
2791-
let isFunctionLevelBinding = isFunctionLike(list.parent.parent);
2806+
let isModuleLevelBinding = list.parent.parent.kind === SyntaxKind.ModuleBlock;
2807+
let isFunctionLevelBinding =
2808+
list.parent.parent.kind === SyntaxKind.Block && isFunctionLike(list.parent.parent.parent);
27922809
if (isSourceFileLevelBinding || isModuleLevelBinding || isFunctionLevelBinding) {
27932810
return;
27942811
}
@@ -2801,7 +2818,7 @@ module ts {
28012818

28022819
var hasConflictsInEnclosingScope =
28032820
!resolver.isUnknownIdentifier(parent, (<Identifier>node).text) ||
2804-
hasConflictsWithTempVariables((<Identifier>node).text);
2821+
nameConflictsWithSomeTempVariable((<Identifier>node).text);
28052822

28062823
if (hasConflictsInEnclosingScope) {
28072824
let variableId = resolver.getBlockScopedVariableId(<Identifier>node);

0 commit comments

Comments
 (0)