Skip to content

Commit 0448eeb

Browse files
committed
Merge remote-tracking branch 'refs/remotes/Microsoft/master' into tsconfigpath
2 parents 8ca6b31 + 7389922 commit 0448eeb

34 files changed

Lines changed: 880 additions & 239 deletions

scripts/tslint/preferConstRule.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ class PreferConstWalker extends Lint.RuleWalker {
8585

8686
visitBinaryExpression(node: ts.BinaryExpression) {
8787
if (isAssignmentOperator(node.operatorToken.kind)) {
88-
this.visitLHSExpressions(node.left);
88+
this.visitLeftHandSideExpression(node.left);
8989
}
9090
super.visitBinaryExpression(node);
9191
}
9292

93-
private visitLHSExpressions(node: ts.Expression) {
93+
private visitLeftHandSideExpression(node: ts.Expression) {
9494
while (node.kind === ts.SyntaxKind.ParenthesizedExpression) {
9595
node = (node as ts.ParenthesizedExpression).expression;
9696
}
@@ -106,18 +106,23 @@ class PreferConstWalker extends Lint.RuleWalker {
106106
if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) {
107107
const pattern = node as ts.ObjectLiteralExpression;
108108
for (const element of pattern.properties) {
109-
if (element.name.kind === ts.SyntaxKind.Identifier) {
110-
this.markAssignment(element.name as ts.Identifier);
109+
const kind = element.kind;
110+
111+
if (kind === ts.SyntaxKind.ShorthandPropertyAssignment) {
112+
this.markAssignment((element as ts.ShorthandPropertyAssignment).name);
113+
}
114+
else if (kind === ts.SyntaxKind.PropertyAssignment) {
115+
this.visitLeftHandSideExpression((element as ts.PropertyAssignment).initializer);
111116
}
112-
else if (isBindingPattern(element.name)) {
113-
this.visitBindingPatternIdentifiers(element.name as ts.BindingPattern);
117+
else {
118+
// Should we throw an exception?
114119
}
115120
}
116121
}
117122
else if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
118123
const pattern = node as ts.ArrayLiteralExpression;
119124
for (const element of pattern.elements) {
120-
this.visitLHSExpressions(element);
125+
this.visitLeftHandSideExpression(element);
121126
}
122127
}
123128
}
@@ -145,7 +150,7 @@ class PreferConstWalker extends Lint.RuleWalker {
145150

146151
private visitAnyUnaryExpression(node: ts.PrefixUnaryExpression | ts.PostfixUnaryExpression) {
147152
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) {
148-
this.visitLHSExpressions(node.operand);
153+
this.visitLeftHandSideExpression(node.operand);
149154
}
150155
}
151156

@@ -211,12 +216,12 @@ class PreferConstWalker extends Lint.RuleWalker {
211216
}
212217
}
213218

214-
private collectNameIdentifiers(value: ts.VariableDeclaration, node: ts.Identifier | ts.BindingPattern, table: ts.Map<DeclarationUsages>) {
219+
private collectNameIdentifiers(declaration: ts.VariableDeclaration, node: ts.Identifier | ts.BindingPattern, table: ts.Map<DeclarationUsages>) {
215220
if (node.kind === ts.SyntaxKind.Identifier) {
216-
table[(node as ts.Identifier).text] = {declaration: value, usages: 0};
221+
table[(node as ts.Identifier).text] = { declaration, usages: 0 };
217222
}
218223
else {
219-
this.collectBindingPatternIdentifiers(value, node as ts.BindingPattern, table);
224+
this.collectBindingPatternIdentifiers(declaration, node as ts.BindingPattern, table);
220225
}
221226
}
222227

src/compiler/binder.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ namespace ts {
139139
file.classifiableNames = classifiableNames;
140140
}
141141

142+
file = undefined;
143+
options = undefined;
142144
parent = undefined;
143145
container = undefined;
144146
blockScopeContainer = undefined;

src/compiler/checker.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -476,15 +476,41 @@ namespace ts {
476476
// Locals of a source file are not in scope (because they get merged into the global symbol table)
477477
if (location.locals && !isGlobalSourceFile(location)) {
478478
if (result = getSymbol(location.locals, name, meaning)) {
479-
// Type parameters of a function are in scope in the entire function declaration, including the parameter
480-
// list and return type. However, local types are only in scope in the function body.
481-
if (!(meaning & SymbolFlags.Type) ||
482-
!(result.flags & (SymbolFlags.Type & ~SymbolFlags.TypeParameter)) ||
483-
!isFunctionLike(location) ||
484-
lastLocation === (<FunctionLikeDeclaration>location).body) {
479+
let useResult = true;
480+
if (isFunctionLike(location) && lastLocation && lastLocation !== (<FunctionLikeDeclaration>location).body) {
481+
// symbol lookup restrictions for function-like declarations
482+
// - Type parameters of a function are in scope in the entire function declaration, including the parameter
483+
// list and return type. However, local types are only in scope in the function body.
484+
// - parameters are only in the scope of function body
485+
if (meaning & result.flags & SymbolFlags.Type) {
486+
useResult = result.flags & SymbolFlags.TypeParameter
487+
// type parameters are visible in parameter list, return type and type parameter list
488+
? lastLocation === (<FunctionLikeDeclaration>location).type ||
489+
lastLocation.kind === SyntaxKind.Parameter ||
490+
lastLocation.kind === SyntaxKind.TypeParameter
491+
// local types not visible outside the function body
492+
: false;
493+
}
494+
if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) {
495+
// parameters are visible only inside function body, parameter list and return type
496+
// technically for parameter list case here we might mix parameters and variables declared in function,
497+
// however it is detected separately when checking initializers of parameters
498+
// to make sure that they reference no variables declared after them.
499+
useResult =
500+
lastLocation.kind === SyntaxKind.Parameter ||
501+
(
502+
lastLocation === (<FunctionLikeDeclaration>location).type &&
503+
result.valueDeclaration.kind === SyntaxKind.Parameter
504+
);
505+
}
506+
}
507+
508+
if (useResult) {
485509
break loop;
486510
}
487-
result = undefined;
511+
else {
512+
result = undefined;
513+
}
488514
}
489515
}
490516
switch (location.kind) {
@@ -9879,7 +9905,7 @@ namespace ts {
98799905
return type;
98809906
}
98819907

9882-
function checkFunctionExpressionOrObjectLiteralMethodBody(node: FunctionExpression | MethodDeclaration) {
9908+
function checkFunctionExpressionOrObjectLiteralMethodBody(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
98839909
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
98849910

98859911
const isAsync = isAsyncFunctionLike(node);

src/compiler/emitter.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
516516
let decorateEmitted: boolean;
517517
let paramEmitted: boolean;
518518
let awaiterEmitted: boolean;
519-
let tempFlags: TempFlags;
519+
let tempFlags: TempFlags = 0;
520520
let tempVariables: Identifier[];
521521
let tempParameters: Identifier[];
522522
let externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[];
@@ -584,33 +584,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
584584
return doEmit;
585585

586586
function doEmit(jsFilePath: string, rootFile?: SourceFile) {
587-
// reset the state
588-
writer.reset();
589-
currentSourceFile = undefined;
590-
currentText = undefined;
591-
currentLineMap = undefined;
592-
exportFunctionForFile = undefined;
593587
generatedNameSet = {};
594588
nodeToGeneratedName = [];
595-
computedPropertyNamesToGeneratedNames = undefined;
596-
convertedLoopState = undefined;
597-
598-
extendsEmitted = false;
599-
decorateEmitted = false;
600-
paramEmitted = false;
601-
awaiterEmitted = false;
602-
tempFlags = 0;
603-
tempVariables = undefined;
604-
tempParameters = undefined;
605-
externalImports = undefined;
606-
exportSpecifiers = undefined;
607-
exportEquals = undefined;
608-
hasExportStars = undefined;
609-
detachedCommentsInfo = undefined;
610-
sourceMapData = undefined;
611-
isEs6Module = false;
612-
renamedDependencies = undefined;
613-
isCurrentFileExternalModule = false;
614589
root = rootFile;
615590

616591
if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
@@ -634,6 +609,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
634609

635610
writeLine();
636611
writeEmittedFiles(writer.getText(), jsFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM);
612+
613+
// reset the state
614+
writer.reset();
615+
currentSourceFile = undefined;
616+
currentText = undefined;
617+
currentLineMap = undefined;
618+
exportFunctionForFile = undefined;
619+
generatedNameSet = undefined;
620+
nodeToGeneratedName = undefined;
621+
computedPropertyNamesToGeneratedNames = undefined;
622+
convertedLoopState = undefined;
623+
extendsEmitted = false;
624+
decorateEmitted = false;
625+
paramEmitted = false;
626+
awaiterEmitted = false;
627+
tempFlags = 0;
628+
tempVariables = undefined;
629+
tempParameters = undefined;
630+
externalImports = undefined;
631+
exportSpecifiers = undefined;
632+
exportEquals = undefined;
633+
hasExportStars = undefined;
634+
detachedCommentsInfo = undefined;
635+
sourceMapData = undefined;
636+
isEs6Module = false;
637+
renamedDependencies = undefined;
638+
isCurrentFileExternalModule = false;
639+
root = undefined;
637640
}
638641

639642
function emitSourceFile(sourceFile: SourceFile): void {

0 commit comments

Comments
 (0)