Skip to content

Commit 9e604f7

Browse files
authored
Merge pull request #25611 from Microsoft/mergeMaster7-12
Merge master into release-3.0
2 parents f4e74d1 + a6b02f2 commit 9e604f7

File tree

93 files changed

+2070
-1242
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+2070
-1242
lines changed

src/compiler/binder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,11 @@ namespace ts {
225225
node.symbol = symbol;
226226
symbol.declarations = append(symbol.declarations, node);
227227

228-
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
228+
if (symbolFlags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.Module | SymbolFlags.Variable) && !symbol.exports) {
229229
symbol.exports = createSymbolTable();
230230
}
231231

232-
if (symbolFlags & SymbolFlags.HasMembers && !symbol.members) {
232+
if (symbolFlags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && !symbol.members) {
233233
symbol.members = createSymbolTable();
234234
}
235235

src/compiler/checker.ts

Lines changed: 181 additions & 78 deletions
Large diffs are not rendered by default.

src/compiler/core.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,6 +1866,9 @@ namespace ts {
18661866
if (candidateName !== undefined && Math.abs(candidateName.length - nameLowerCase.length) <= maximumLengthDifference) {
18671867
const candidateNameLowerCase = candidateName.toLowerCase();
18681868
if (candidateNameLowerCase === nameLowerCase) {
1869+
if (candidateName === name) {
1870+
continue;
1871+
}
18691872
return candidate;
18701873
}
18711874
if (justCheckExactMatches) {

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,6 +2056,10 @@
20562056
"category": "Error",
20572057
"code": 2574
20582058
},
2059+
"No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments.": {
2060+
"category": "Error",
2061+
"code": 2575
2062+
},
20592063
"JSX element attributes type '{0}' may not be a union type.": {
20602064
"category": "Error",
20612065
"code": 2600
@@ -4017,6 +4021,10 @@
40174021
"category": "Error",
40184022
"code": 8029
40194023
},
4024+
"The type of a function declaration must be callable.": {
4025+
"category": "Error",
4026+
"code": 8030
4027+
},
40204028
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
40214029
"category": "Error",
40224030
"code": 9002

src/compiler/symbolWalker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ namespace ts {
171171
}
172172
const t = getTypeOfSymbol(symbol);
173173
visitType(t); // Should handle members on classes and such
174-
if (symbol.flags & SymbolFlags.HasExports) {
175-
symbol.exports!.forEach(visitSymbol);
174+
if (symbol.exports) {
175+
symbol.exports.forEach(visitSymbol);
176176
}
177177
forEach(symbol.declarations, d => {
178178
// Type queries are too far resolved when we just visit the symbol's type

src/compiler/transformers/es2015.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ namespace ts {
529529
createVariableStatement(/*modifiers*/ undefined,
530530
createVariableDeclarationList(taggedTemplateStringDeclarations)));
531531
}
532-
prependStatements(statements, endLexicalEnvironment());
532+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
533533
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
534534
return updateSourceFileNode(
535535
node,
@@ -837,7 +837,7 @@ namespace ts {
837837
setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps);
838838
statements.push(statement);
839839

840-
prependStatements(statements, endLexicalEnvironment());
840+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
841841

842842
const block = createBlock(setTextRange(createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
843843
setEmitFlags(block, EmitFlags.NoComments);
@@ -980,7 +980,7 @@ namespace ts {
980980
);
981981
}
982982

983-
prependStatements(statements, endLexicalEnvironment());
983+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
984984

985985
if (constructor) {
986986
prependCaptureNewTargetIfNeeded(statements, constructor, /*copyOnWrite*/ false);
@@ -1892,7 +1892,7 @@ namespace ts {
18921892
}
18931893

18941894
const lexicalEnvironment = context.endLexicalEnvironment();
1895-
prependStatements(statements, lexicalEnvironment);
1895+
addStatementsAfterPrologue(statements, lexicalEnvironment);
18961896
prependCaptureNewTargetIfNeeded(statements, node, /*copyOnWrite*/ false);
18971897

18981898
// If we added any final generated statements, this must be a multi-line block
@@ -2707,7 +2707,7 @@ namespace ts {
27072707
if (loopOutParameters.length) {
27082708
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
27092709
}
2710-
prependStatements(statements, lexicalEnvironment);
2710+
addStatementsAfterPrologue(statements, lexicalEnvironment);
27112711
loopBody = createBlock(statements, /*multiline*/ true);
27122712
}
27132713

src/compiler/transformers/es2017.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ namespace ts {
413413
)
414414
);
415415

416-
prependStatements(statements, endLexicalEnvironment());
416+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
417417

418418
const block = createBlock(statements, /*multiLine*/ true);
419419
setTextRange(block, node.body);

src/compiler/transformers/esnext.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ namespace ts {
675675
)
676676
);
677677

678-
prependStatements(statements, endLexicalEnvironment());
678+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
679679
const block = updateBlock(node.body!, statements);
680680

681681
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
@@ -707,7 +707,7 @@ namespace ts {
707707
const leadingStatements = endLexicalEnvironment();
708708
if (statementOffset > 0 || some(statements) || some(leadingStatements)) {
709709
const block = convertToFunctionBody(body, /*multiLine*/ true);
710-
prependStatements(statements, leadingStatements);
710+
addStatementsAfterPrologue(statements, leadingStatements);
711711
addRange(statements, block.statements.slice(statementOffset));
712712
return updateBlock(block, setTextRange(createNodeArray(statements), block.statements));
713713
}

src/compiler/transformers/generators.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ namespace ts {
587587
transformAndEmitStatements(body.statements, statementOffset);
588588

589589
const buildResult = build();
590-
prependStatements(statements, endLexicalEnvironment());
590+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
591591
statements.push(createReturn(buildResult));
592592

593593
// Restore previous generator state

src/compiler/transformers/module/module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ namespace ts {
9797
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
9898
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
9999
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
100-
prependStatements(statements, endLexicalEnvironment());
100+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
101101

102102
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
103103
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
@@ -426,7 +426,7 @@ namespace ts {
426426

427427
// End the lexical environment for the module body
428428
// and merge any new lexical declarations.
429-
prependStatements(statements, endLexicalEnvironment());
429+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
430430

431431
const body = createBlock(statements, /*multiLine*/ true);
432432
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {

src/compiler/transformers/module/system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ namespace ts {
257257
// We emit hoisted variables early to align roughly with our previous emit output.
258258
// Two key differences in this approach are:
259259
// - Temporary variables will appear at the top rather than at the bottom of the file
260-
prependStatements(statements, endLexicalEnvironment());
260+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
261261

262262
const exportStarFunction = addExportStarIfNeeded(statements)!; // TODO: GH#18217
263263
const moduleObject = createObjectLiteral([

src/compiler/transformers/ts.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ namespace ts {
682682
setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps);
683683
statements.push(statement);
684684

685-
prependStatements(statements, context.endLexicalEnvironment());
685+
addStatementsAfterPrologue(statements, context.endLexicalEnvironment());
686686

687687
const iife = createImmediatelyInvokedArrowFunction(statements);
688688
setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper);
@@ -2711,7 +2711,7 @@ namespace ts {
27112711
const statements: Statement[] = [];
27122712
startLexicalEnvironment();
27132713
const members = map(node.members, transformEnumMember);
2714-
prependStatements(statements, endLexicalEnvironment());
2714+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
27152715
addRange(statements, members);
27162716

27172717
currentNamespaceContainerName = savedCurrentNamespaceLocalName;
@@ -3026,7 +3026,7 @@ namespace ts {
30263026
statementsLocation = moveRangePos(moduleBlock.statements, -1);
30273027
}
30283028

3029-
prependStatements(statements, endLexicalEnvironment());
3029+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
30303030
currentNamespaceContainerName = savedCurrentNamespaceContainerName;
30313031
currentNamespace = savedCurrentNamespace;
30323032
currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;

src/compiler/types.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2936,7 +2936,7 @@ namespace ts {
29362936
*/
29372937
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
29382938
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
2939-
getTypeAtLocation(node: Node): Type | undefined;
2939+
getTypeAtLocation(node: Node): Type;
29402940
getTypeFromTypeNode(node: TypeNode): Type;
29412941

29422942
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
@@ -3439,9 +3439,6 @@ namespace ts {
34393439

34403440
ExportHasLocal = Function | Class | Enum | ValueModule,
34413441

3442-
HasExports = Class | Enum | Module | Variable,
3443-
HasMembers = Class | Interface | TypeLiteral | ObjectLiteral,
3444-
34453442
BlockScoped = BlockScopedVariable | Class | Enum,
34463443

34473444
PropertyOrAccessor = Property | Accessor,

src/compiler/utilities.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -401,21 +401,18 @@ namespace ts {
401401
}
402402

403403
/**
404-
* Appends a range of value to begin of an array, returning the array.
405-
*
406-
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
407-
* is created if `value` was appended.
408-
* @param from The values to append to the array. If `from` is `undefined`, nothing is
409-
* appended. If an element of `from` is `undefined`, that element is not appended.
404+
* Prepends statements to an array while taking care of prologue directives.
410405
*/
411-
export function prependStatements<T extends Statement>(to: T[], from: ReadonlyArray<T> | undefined): T[] | undefined {
406+
export function addStatementsAfterPrologue<T extends Statement>(to: T[], from: ReadonlyArray<T> | undefined): T[] {
412407
if (from === undefined || from.length === 0) return to;
413-
if (to === undefined) return from.slice();
414-
const prologue = to.length && isPrologueDirective(to[0]) && to.shift();
415-
to.unshift(...from);
416-
if (prologue) {
417-
to.unshift(prologue);
408+
let statementIndex = 0;
409+
// skip all prologue directives to insert at the correct position
410+
for (; statementIndex < to.length; ++statementIndex) {
411+
if (!isPrologueDirective(to[statementIndex])) {
412+
break;
413+
}
418414
}
415+
to.splice(statementIndex, 0, ...from);
419416
return to;
420417
}
421418

@@ -912,9 +909,7 @@ namespace ts {
912909
}
913910

914911
export function isLiteralImportTypeNode(n: Node): n is LiteralImportTypeNode {
915-
return n.kind === SyntaxKind.ImportType &&
916-
(n as ImportTypeNode).argument.kind === SyntaxKind.LiteralType &&
917-
isStringLiteral(((n as ImportTypeNode).argument as LiteralTypeNode).literal);
912+
return isImportTypeNode(n) && isLiteralTypeNode(n.argument) && isStringLiteral(n.argument.literal);
918913
}
919914

920915
export function isPrologueDirective(node: Node): node is PrologueDirective {
@@ -8090,4 +8085,20 @@ namespace ts {
80908085
Debug.assert(index !== -1);
80918086
return arr.slice(index);
80928087
}
8088+
8089+
export function minAndMax<T>(arr: ReadonlyArray<T>, getValue: (value: T) => number): { readonly min: number, readonly max: number } {
8090+
Debug.assert(arr.length !== 0);
8091+
let min = getValue(arr[0]);
8092+
let max = min;
8093+
for (let i = 1; i < arr.length; i++) {
8094+
const value = getValue(arr[i]);
8095+
if (value < min) {
8096+
min = value;
8097+
}
8098+
else if (value > max) {
8099+
max = value;
8100+
}
8101+
}
8102+
return { min, max };
8103+
}
80938104
}

src/compiler/visitor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,8 +1476,8 @@ namespace ts {
14761476
}
14771477

14781478
return isNodeArray(statements)
1479-
? setTextRange(createNodeArray(prependStatements(statements.slice(), declarations)), statements)
1480-
: prependStatements(statements, declarations);
1479+
? setTextRange(createNodeArray(addStatementsAfterPrologue(statements.slice(), declarations)), statements)
1480+
: addStatementsAfterPrologue(statements, declarations);
14811481
}
14821482

14831483
/**

src/harness/fourslash.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4767,7 +4767,7 @@ namespace FourSlashInterface {
47674767
}
47684768

47694769
export interface VerifyCompletionsOptions {
4770-
readonly marker?: ArrayOrSingle<string>;
4770+
readonly marker?: ArrayOrSingle<string | FourSlash.Marker>;
47714771
readonly isNewIdentifierLocation?: boolean;
47724772
readonly exact?: ArrayOrSingle<ExpectedCompletionEntry>;
47734773
readonly includes?: ArrayOrSingle<ExpectedCompletionEntry>;

src/services/codefixes/fixAddMissingMember.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ namespace ts.codefix {
124124
const { parent } = token;
125125
if (!isPropertyAccessExpression(parent)) return undefined;
126126

127-
const leftExpressionType = skipConstraint(checker.getTypeAtLocation(parent.expression)!);
127+
const leftExpressionType = skipConstraint(checker.getTypeAtLocation(parent.expression));
128128
const { symbol } = leftExpressionType;
129129
if (!symbol || !symbol.declarations) return undefined;
130130

@@ -183,7 +183,7 @@ namespace ts.codefix {
183183
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
184184
const binaryExpression = token.parent.parent as BinaryExpression;
185185
const otherExpression = token.parent === binaryExpression.left ? binaryExpression.right : binaryExpression.left;
186-
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression)!)); // TODO: GH#18217
186+
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression)));
187187
typeNode = checker.typeToTypeNode(widenedType, classDeclaration);
188188
}
189189
return typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);

src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace ts.codefix {
3434

3535
function addMissingMembers(classDeclaration: ClassLikeDeclaration, sourceFile: SourceFile, checker: TypeChecker, changeTracker: textChanges.ChangeTracker, preferences: UserPreferences): void {
3636
const extendsNode = getEffectiveBaseTypeNode(classDeclaration)!;
37-
const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode)!;
37+
const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode);
3838

3939
// Note that this is ultimately derived from a map indexed by symbol names,
4040
// so duplicates cannot occur.

src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace ts.codefix {
5151
const implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
5252
const nonPrivateAndNotExistedInHeritageClauseMembers = implementedTypeSymbols.filter(and(symbolPointsToNonPrivateMember, symbol => !maybeHeritageClauseSymbol.has(symbol.escapedName)));
5353

54-
const classType = checker.getTypeAtLocation(classDeclaration)!;
54+
const classType = checker.getTypeAtLocation(classDeclaration);
5555

5656
if (!classType.getNumberIndexType()) {
5757
createMissingIndexSignatureDeclaration(implementedType, IndexKind.Number);

src/services/codefixes/fixInvalidImportSyntax.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ namespace ts.codefix {
7777
}
7878

7979
function getImportCodeFixesForExpression(context: CodeFixContext, expr: Node): CodeFixAction[] | undefined {
80-
const type = context.program.getTypeChecker().getTypeAtLocation(expr)!; // TODO: GH#18217
80+
const type = context.program.getTypeChecker().getTypeAtLocation(expr);
8181
if (!(type.symbol && (type.symbol as TransientSymbol).originatingImport)) {
8282
return [];
8383
}

src/services/codefixes/fixSpelling.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ namespace ts.codefix {
3535
let suggestion: string | undefined;
3636
if (isPropertyAccessExpression(node.parent) && node.parent.name === node) {
3737
Debug.assert(node.kind === SyntaxKind.Identifier);
38-
const containingType = checker.getTypeAtLocation(node.parent.expression)!;
38+
const containingType = checker.getTypeAtLocation(node.parent.expression);
3939
suggestion = checker.getSuggestionForNonexistentProperty(node as Identifier, containingType);
4040
}
4141
else if (isImportSpecifier(node.parent) && node.parent.name === node) {

src/services/codefixes/inferFromUsage.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ namespace ts.codefix {
401401
case SyntaxKind.LessThanEqualsToken:
402402
case SyntaxKind.GreaterThanToken:
403403
case SyntaxKind.GreaterThanEqualsToken:
404-
const operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left)!;
404+
const operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
405405
if (operandType.flags & TypeFlags.EnumLike) {
406406
addCandidateType(usageContext, operandType);
407407
}
@@ -412,7 +412,7 @@ namespace ts.codefix {
412412

413413
case SyntaxKind.PlusEqualsToken:
414414
case SyntaxKind.PlusToken:
415-
const otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left)!;
415+
const otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left);
416416
if (otherOperandType.flags & TypeFlags.EnumLike) {
417417
addCandidateType(usageContext, otherOperandType);
418418
}
@@ -472,7 +472,7 @@ namespace ts.codefix {
472472

473473
if (parent.arguments) {
474474
for (const argument of parent.arguments) {
475-
callContext.argumentTypes.push(checker.getTypeAtLocation(argument)!);
475+
callContext.argumentTypes.push(checker.getTypeAtLocation(argument));
476476
}
477477
}
478478

@@ -501,7 +501,7 @@ namespace ts.codefix {
501501
return;
502502
}
503503
else {
504-
const indexType = checker.getTypeAtLocation(parent)!;
504+
const indexType = checker.getTypeAtLocation(parent);
505505
const indexUsageContext = {};
506506
inferTypeFromContext(parent, checker, indexUsageContext);
507507
if (indexType.flags & TypeFlags.NumberLike) {

0 commit comments

Comments
 (0)