Skip to content

Commit f15909b

Browse files
author
Kanchalai Tanglertsampan
committed
Merge branch 'master' into master-16763
2 parents 1ac95c2 + bb3253e commit f15909b

23 files changed

+585
-390
lines changed

scripts/tslint/booleanTriviaRule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
2727
/** Skip certain function/method names whose parameter names are not informative. */
2828
function shouldIgnoreCalledExpression(expression: ts.Expression): boolean {
2929
if (expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
30-
const methodName = (expression as ts.PropertyAccessExpression).name.text;
30+
const methodName = (expression as ts.PropertyAccessExpression).name.text as string;
3131
if (methodName.indexOf("set") === 0) {
3232
return true;
3333
}
@@ -44,7 +44,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
4444
}
4545
}
4646
else if (expression.kind === ts.SyntaxKind.Identifier) {
47-
const functionName = (expression as ts.Identifier).text;
47+
const functionName = (expression as ts.Identifier).text as string;
4848
if (functionName.indexOf("set") === 0) {
4949
return true;
5050
}

src/compiler/checker.ts

Lines changed: 60 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ namespace ts {
5656
let enumCount = 0;
5757
let symbolInstantiationDepth = 0;
5858

59-
const emptyArray: any[] = [];
6059
const emptySymbols = createSymbolTable();
6160

6261
const compilerOptions = host.getCompilerOptions();
@@ -84,9 +83,9 @@ namespace ts {
8483
// extra cost of calling `getParseTreeNode` when calling these functions from inside the
8584
// checker.
8685
const checker: TypeChecker = {
87-
getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"),
88-
getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"),
89-
getSymbolCount: () => sum(host.getSourceFiles(), "symbolCount") + symbolCount,
86+
getNodeCount: () => sum<"nodeCount">(host.getSourceFiles(), "nodeCount"),
87+
getIdentifierCount: () => sum<"identifierCount">(host.getSourceFiles(), "identifierCount"),
88+
getSymbolCount: () => sum<"symbolCount">(host.getSourceFiles(), "symbolCount") + symbolCount,
9089
getTypeCount: () => typeCount,
9190
isUndefinedSymbol: symbol => symbol === undefinedSymbol,
9291
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
@@ -8735,11 +8734,12 @@ namespace ts {
87358734
containingMessageChain?: DiagnosticMessageChain): boolean {
87368735

87378736
let errorInfo: DiagnosticMessageChain;
8737+
let maybeKeys: string[];
87388738
let sourceStack: Type[];
87398739
let targetStack: Type[];
8740-
let maybeStack: Map<RelationComparisonResult>[];
8741-
let expandingFlags: number;
8740+
let maybeCount = 0;
87428741
let depth = 0;
8742+
let expandingFlags = 0;
87438743
let overflow = false;
87448744
let isIntersectionConstituent = false;
87458745

@@ -9107,10 +9107,15 @@ namespace ts {
91079107
return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
91089108
}
91099109
}
9110-
if (depth > 0) {
9111-
for (let i = 0; i < depth; i++) {
9110+
if (!maybeKeys) {
9111+
maybeKeys = [];
9112+
sourceStack = [];
9113+
targetStack = [];
9114+
}
9115+
else {
9116+
for (let i = 0; i < maybeCount; i++) {
91129117
// If source and target are already being compared, consider them related with assumptions
9113-
if (maybeStack[i].get(id)) {
9118+
if (id === maybeKeys[i]) {
91149119
return Ternary.Maybe;
91159120
}
91169121
}
@@ -9119,16 +9124,11 @@ namespace ts {
91199124
return Ternary.False;
91209125
}
91219126
}
9122-
else {
9123-
sourceStack = [];
9124-
targetStack = [];
9125-
maybeStack = [];
9126-
expandingFlags = 0;
9127-
}
9127+
const maybeStart = maybeCount;
9128+
maybeKeys[maybeCount] = id;
9129+
maybeCount++;
91289130
sourceStack[depth] = source;
91299131
targetStack[depth] = target;
9130-
maybeStack[depth] = createMap<RelationComparisonResult>();
9131-
maybeStack[depth].set(id, RelationComparisonResult.Succeeded);
91329132
depth++;
91339133
const saveExpandingFlags = expandingFlags;
91349134
if (!(expandingFlags & 1) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= 1;
@@ -9137,15 +9137,19 @@ namespace ts {
91379137
expandingFlags = saveExpandingFlags;
91389138
depth--;
91399139
if (result) {
9140-
const maybeCache = maybeStack[depth];
9141-
// If result is definitely true, copy assumptions to global cache, else copy to next level up
9142-
const destinationCache = (result === Ternary.True || depth === 0) ? relation : maybeStack[depth - 1];
9143-
copyEntries(maybeCache, destinationCache);
9140+
if (result === Ternary.True || depth === 0) {
9141+
// If result is definitely true, record all maybe keys as having succeeded
9142+
for (let i = maybeStart; i < maybeCount; i++) {
9143+
relation.set(maybeKeys[i], RelationComparisonResult.Succeeded);
9144+
}
9145+
maybeCount = maybeStart;
9146+
}
91449147
}
91459148
else {
9146-
// A false result goes straight into global cache (when something is false under assumptions it
9147-
// will also be false without assumptions)
9149+
// A false result goes straight into global cache (when something is false under
9150+
// assumptions it will also be false without assumptions)
91489151
relation.set(id, reportErrors ? RelationComparisonResult.FailedAndReported : RelationComparisonResult.Failed);
9152+
maybeCount = maybeStart;
91499153
}
91509154
return result;
91519155
}
@@ -12004,9 +12008,9 @@ namespace ts {
1200412008
}
1200512009

1200612010
const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
12011+
let declaration = localOrExportSymbol.valueDeclaration;
1200712012

1200812013
if (localOrExportSymbol.flags & SymbolFlags.Class) {
12009-
const declaration = localOrExportSymbol.valueDeclaration;
1201012014
// Due to the emit for class decorators, any reference to the class from inside of the class body
1201112015
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
1201212016
// behavior of class names in ES6.
@@ -12048,7 +12052,6 @@ namespace ts {
1204812052
checkNestedBlockScopedBinding(node, symbol);
1204912053

1205012054
const type = getDeclaredOrApparentType(localOrExportSymbol, node);
12051-
const declaration = localOrExportSymbol.valueDeclaration;
1205212055
const assignmentKind = getAssignmentTargetKind(node);
1205312056

1205412057
if (assignmentKind) {
@@ -12062,11 +12065,26 @@ namespace ts {
1206212065
}
1206312066
}
1206412067

12068+
const isAlias = localOrExportSymbol.flags & SymbolFlags.Alias;
12069+
1206512070
// We only narrow variables and parameters occurring in a non-assignment position. For all other
1206612071
// entities we simply return the declared type.
12067-
if (!(localOrExportSymbol.flags & SymbolFlags.Variable) || assignmentKind === AssignmentKind.Definite || !declaration) {
12072+
if (localOrExportSymbol.flags & SymbolFlags.Variable) {
12073+
if (assignmentKind === AssignmentKind.Definite) {
12074+
return type;
12075+
}
12076+
}
12077+
else if (isAlias) {
12078+
declaration = find<Declaration>(symbol.declarations, isSomeImportDeclaration);
12079+
}
12080+
else {
1206812081
return type;
1206912082
}
12083+
12084+
if (!declaration) {
12085+
return type;
12086+
}
12087+
1207012088
// The declaration container is the innermost function that encloses the declaration of the variable
1207112089
// or parameter. The flow container is the innermost function starting with which we analyze the control
1207212090
// flow graph to determine the control flow based type.
@@ -12085,7 +12103,7 @@ namespace ts {
1208512103
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
1208612104
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
1208712105
// declaration container are the same).
12088-
const assumeInitialized = isParameter || isOuterVariable ||
12106+
const assumeInitialized = isParameter || isAlias || isOuterVariable ||
1208912107
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
1209012108
node.parent.kind === SyntaxKind.NonNullExpression ||
1209112109
isInAmbientContext(declaration);
@@ -24771,4 +24789,19 @@ namespace ts {
2477124789
return isDeclarationName(name);
2477224790
}
2477324791
}
24792+
24793+
function isSomeImportDeclaration(decl: Node): boolean {
24794+
switch (decl.kind) {
24795+
case SyntaxKind.ImportClause: // For default import
24796+
case SyntaxKind.ImportEqualsDeclaration:
24797+
case SyntaxKind.NamespaceImport:
24798+
case SyntaxKind.ImportSpecifier: // For rename import `x as y`
24799+
return true;
24800+
case SyntaxKind.Identifier:
24801+
// For regular import, `decl` is an Identifier under the ImportSpecifier.
24802+
return decl.parent.kind === SyntaxKind.ImportSpecifier;
24803+
default:
24804+
return false;
24805+
}
24806+
}
2477424807
}

src/compiler/core.ts

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -162,50 +162,6 @@ namespace ts {
162162
};
163163
}
164164

165-
export function createFileMap<T>(keyMapper: (key: string) => string): FileMap<T> {
166-
const files = createMap<T>();
167-
return {
168-
get,
169-
set,
170-
contains,
171-
remove,
172-
forEachValue: forEachValueInMap,
173-
getKeys,
174-
clear,
175-
};
176-
177-
function forEachValueInMap(f: (key: Path, value: T) => void) {
178-
files.forEach((file, key) => {
179-
f(<Path>key, file);
180-
});
181-
}
182-
183-
function getKeys() {
184-
return arrayFrom(files.keys()) as Path[];
185-
}
186-
187-
// path should already be well-formed so it does not need to be normalized
188-
function get(path: Path): T {
189-
return files.get(keyMapper(path));
190-
}
191-
192-
function set(path: Path, value: T) {
193-
files.set(keyMapper(path), value);
194-
}
195-
196-
function contains(path: Path) {
197-
return files.has(keyMapper(path));
198-
}
199-
200-
function remove(path: Path) {
201-
files.delete(keyMapper(path));
202-
}
203-
204-
function clear() {
205-
files.clear();
206-
}
207-
}
208-
209165
export function toPath(fileName: string, basePath: string, getCanonicalFileName: (path: string) => string): Path {
210166
const nonCanonicalizedPath = isRootedDiskPath(fileName)
211167
? normalizePath(fileName)
@@ -744,7 +700,7 @@ namespace ts {
744700
return result;
745701
}
746702

747-
export function sum(array: any[], prop: string): number {
703+
export function sum<K extends string>(array: { [x in K]: number }[], prop: K): number {
748704
let result = 0;
749705
for (const v of array) {
750706
result += v[prop];

0 commit comments

Comments
 (0)