Skip to content

Commit 59e2617

Browse files
committed
Merge branch 'master' into bind-toplevel-this
2 parents 5831e80 + 47d768c commit 59e2617

File tree

61 files changed

+1528
-469
lines changed

Some content is hidden

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

61 files changed

+1528
-469
lines changed

lib/lib.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ interface Function {
265265
* @param thisArg The object to be used as the this object.
266266
* @param argArray A set of arguments to be passed to the function.
267267
*/
268-
apply(this: Function, thisArg: any, argArray?: any): any;
268+
apply(this: Function, thisArg: any, argArray?: Readonly<ArrayLike<any>>): any;
269269

270270
/**
271271
* Calls a method of an object, substituting another object for the current object.

src/compiler/checker.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,14 +1730,19 @@ namespace ts {
17301730
: resolveSymbol(moduleSymbol.exports.get(name), dontResolveAlias);
17311731
}
17321732

1733+
function isSyntacticDefault(node: Node) {
1734+
return ((isExportAssignment(node) && !node.isExportEquals) || hasModifier(node, ModifierFlags.Default));
1735+
}
1736+
17331737
function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean) {
17341738
if (!allowSyntheticDefaultImports) {
17351739
return false;
17361740
}
17371741
// Declaration files (and ambient modules)
17381742
if (!file || file.isDeclarationFile) {
1739-
// Definitely cannot have a synthetic default if they have a default member specified
1740-
if (resolveExportByName(moduleSymbol, InternalSymbolName.Default, dontResolveAlias)) {
1743+
// Definitely cannot have a synthetic default if they have a syntactic default member specified
1744+
const defaultExportSymbol = resolveExportByName(moduleSymbol, InternalSymbolName.Default, dontResolveAlias);
1745+
if (defaultExportSymbol && defaultExportSymbol.valueDeclaration && isSyntacticDefault(defaultExportSymbol.valueDeclaration)) {
17411746
return false;
17421747
}
17431748
// It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member
@@ -1777,7 +1782,7 @@ namespace ts {
17771782
if (!exportDefaultSymbol && !hasSyntheticDefault) {
17781783
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
17791784
}
1780-
else if (!exportDefaultSymbol && hasSyntheticDefault) {
1785+
else if (hasSyntheticDefault) {
17811786
// per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present
17821787
return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
17831788
}
@@ -8146,6 +8151,9 @@ namespace ts {
81468151
}
81478152
return indexInfo.type;
81488153
}
8154+
if (indexType.flags & TypeFlags.Never) {
8155+
return neverType;
8156+
}
81498157
if (accessExpression && !isConstEnumObjectType(objectType)) {
81508158
if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
81518159
if (getIndexTypeOfType(objectType, IndexKind.Number)) {

src/compiler/transformers/es2015.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,8 +1510,7 @@ namespace ts {
15101510
break;
15111511

15121512
default:
1513-
Debug.failBadSyntaxKind(node);
1514-
break;
1513+
return Debug.failBadSyntaxKind(node);
15151514
}
15161515

15171516
const captureNewTargetStatement = createVariableStatement(
@@ -1922,7 +1921,7 @@ namespace ts {
19221921
return block;
19231922
}
19241923

1925-
function visitFunctionBodyDownLevel(node: FunctionDeclaration | FunctionExpression) {
1924+
function visitFunctionBodyDownLevel(node: FunctionDeclaration | FunctionExpression | AccessorDeclaration) {
19261925
const updated = visitFunctionBody(node.body, functionBodyVisitor, context);
19271926
return updateBlock(
19281927
updated,
@@ -3196,18 +3195,15 @@ namespace ts {
31963195
convertedLoopState = undefined;
31973196
const ancestorFacts = enterSubtree(HierarchyFacts.FunctionExcludes, HierarchyFacts.FunctionIncludes);
31983197
let updated: AccessorDeclaration;
3199-
if (node.transformFlags & TransformFlags.ContainsCapturedLexicalThis) {
3200-
const parameters = visitParameterList(node.parameters, visitor, context);
3201-
const body = transformFunctionBody(node);
3202-
if (node.kind === SyntaxKind.GetAccessor) {
3203-
updated = updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body);
3204-
}
3205-
else {
3206-
updated = updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body);
3207-
}
3198+
const parameters = visitParameterList(node.parameters, visitor, context);
3199+
const body = node.transformFlags & (TransformFlags.ContainsCapturedLexicalThis | TransformFlags.ContainsES2015)
3200+
? transformFunctionBody(node)
3201+
: visitFunctionBodyDownLevel(node);
3202+
if (node.kind === SyntaxKind.GetAccessor) {
3203+
updated = updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body);
32083204
}
32093205
else {
3210-
updated = visitEachChild(node, visitor, context);
3206+
updated = updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body);
32113207
}
32123208
exitSubtree(ancestorFacts, HierarchyFacts.PropagateNewTargetMask, HierarchyFacts.None);
32133209
convertedLoopState = savedConvertedLoopState;

src/compiler/transformers/generators.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,7 @@ namespace ts {
430430
return visitFunctionExpression(<FunctionExpression>node);
431431

432432
default:
433-
Debug.failBadSyntaxKind(node);
434-
return visitEachChild(node, visitor, context);
433+
return Debug.failBadSyntaxKind(node);
435434
}
436435
}
437436

src/compiler/transformers/jsx.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ namespace ts {
7272
return visitJsxFragment(node, /*isChild*/ true);
7373

7474
default:
75-
Debug.failBadSyntaxKind(node);
76-
return undefined;
75+
return Debug.failBadSyntaxKind(node);
7776
}
7877
}
7978

@@ -182,7 +181,7 @@ namespace ts {
182181
return visitJsxExpression(node);
183182
}
184183
else {
185-
Debug.failBadSyntaxKind(node);
184+
return Debug.failBadSyntaxKind(node);
186185
}
187186
}
188187

src/compiler/transformers/ts.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,7 @@ namespace ts {
324324
return node;
325325

326326
default:
327-
Debug.failBadSyntaxKind(node);
328-
return undefined;
327+
return Debug.failBadSyntaxKind(node);
329328
}
330329
}
331330

@@ -531,8 +530,7 @@ namespace ts {
531530
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
532531

533532
default:
534-
Debug.failBadSyntaxKind(node);
535-
return visitEachChild(node, visitor, context);
533+
return Debug.failBadSyntaxKind(node);
536534
}
537535
}
538536

@@ -1870,10 +1868,8 @@ namespace ts {
18701868
return createIdentifier("Boolean");
18711869

18721870
default:
1873-
Debug.failBadSyntaxKind((<LiteralTypeNode>node).literal);
1874-
break;
1871+
return Debug.failBadSyntaxKind((<LiteralTypeNode>node).literal);
18751872
}
1876-
break;
18771873

18781874
case SyntaxKind.NumberKeyword:
18791875
return createIdentifier("Number");
@@ -1900,8 +1896,7 @@ namespace ts {
19001896
break;
19011897

19021898
default:
1903-
Debug.failBadSyntaxKind(node);
1904-
break;
1899+
return Debug.failBadSyntaxKind(node);
19051900
}
19061901

19071902
return createIdentifier("Object");

src/compiler/utilities.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4070,6 +4070,12 @@ namespace ts {
40704070
return { start, length };
40714071
}
40724072

4073+
/* @internal */
4074+
export function createTextRange(pos: number, end: number = pos): TextRange {
4075+
Debug.assert(end >= pos);
4076+
return { pos, end };
4077+
}
4078+
40734079
export function createTextSpanFromBounds(start: number, end: number) {
40744080
return createTextSpan(start, end - start);
40754081
}

src/compiler/visitor.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,11 +1546,11 @@ namespace ts {
15461546
export namespace Debug {
15471547
let isDebugInfoEnabled = false;
15481548

1549-
export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal)
1550-
? (node: Node, message?: string): never => fail(
1549+
export function failBadSyntaxKind(node: Node, message?: string): never {
1550+
return fail(
15511551
`${message || "Unexpected node."}\r\nNode ${formatSyntaxKind(node.kind)} was unexpected.`,
1552-
failBadSyntaxKind)
1553-
: noop as () => never; // TODO: GH#22091
1552+
failBadSyntaxKind);
1553+
}
15541554

15551555
export const assertEachNode = shouldAssert(AssertionLevel.Normal)
15561556
? (nodes: Node[], test: (node: Node) => boolean, message?: string): void => assert(

src/harness/fourslash.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -832,16 +832,21 @@ namespace FourSlash {
832832
}
833833
}
834834

835-
public verifyCompletionsAt(markerName: string, expected: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry>, options?: FourSlashInterface.CompletionsAtOptions) {
835+
public verifyCompletionsAt(markerName: string | ReadonlyArray<string>, expected: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry>, options?: FourSlashInterface.CompletionsAtOptions) {
836+
if (typeof markerName !== "string") {
837+
for (const m of markerName) this.verifyCompletionsAt(m, expected, options);
838+
return;
839+
}
840+
836841
this.goToMarker(markerName);
837842

838843
const actualCompletions = this.getCompletionListAtCaret(options);
839844
if (!actualCompletions) {
840845
this.raiseError(`No completions at position '${this.currentCaretPosition}'.`);
841846
}
842847

843-
if (options && options.isNewIdentifierLocation !== undefined && actualCompletions.isNewIdentifierLocation !== options.isNewIdentifierLocation) {
844-
this.raiseError(`Expected 'isNewIdentifierLocation' to be ${options.isNewIdentifierLocation}, got ${actualCompletions.isNewIdentifierLocation}`);
848+
if (actualCompletions.isNewIdentifierLocation !== (options && options.isNewIdentifierLocation || false)) {
849+
this.raiseError(`Expected 'isNewIdentifierLocation' to be ${options && options.isNewIdentifierLocation}, got ${actualCompletions.isNewIdentifierLocation}`);
845850
}
846851

847852
const actual = actualCompletions.entries;
@@ -3182,9 +3187,7 @@ Actual: ${stringify(fullActual)}`);
31823187
eq(item.hasAction, hasAction, "hasAction");
31833188
eq(item.isRecommended, options && options.isRecommended, "isRecommended");
31843189
eq(item.insertText, options && options.insertText, "insertText");
3185-
if (options && options.replacementSpan) { // TODO: GH#21679
3186-
eq(item.replacementSpan, options && options.replacementSpan && ts.createTextSpanFromRange(options.replacementSpan), "replacementSpan");
3187-
}
3190+
eq(item.replacementSpan, options && options.replacementSpan && ts.createTextSpanFromRange(options.replacementSpan), "replacementSpan");
31883191
}
31893192

31903193
private findFile(indexOrName: string | number) {
@@ -3988,7 +3991,7 @@ namespace FourSlashInterface {
39883991
super(state);
39893992
}
39903993

3991-
public completionsAt(markerName: string, completions: ReadonlyArray<ExpectedCompletionEntry>, options?: CompletionsAtOptions) {
3994+
public completionsAt(markerName: string | ReadonlyArray<string>, completions: ReadonlyArray<ExpectedCompletionEntry>, options?: CompletionsAtOptions) {
39923995
this.state.verifyCompletionsAt(markerName, completions, options);
39933996
}
39943997

src/services/codefixes/convertToEs6Module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ namespace ts.codefix {
257257
changes.replaceNodeWithNodes(sourceFile, statement, newNodes);
258258
}
259259
else {
260-
changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right), { useNonAdjustedEndPosition: true });
260+
changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right));
261261
}
262262
}
263263

src/services/codefixes/disableJsDiagnostics.ts

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace ts.codefix {
2727
fixId: undefined,
2828
}];
2929

30-
if (isValidSuppressLocation(sourceFile, span.start)) {
30+
if (textChanges.isValidLocationToAddComment(sourceFile, span.start)) {
3131
fixes.unshift({
3232
description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message),
3333
changes: textChanges.ChangeTracker.with(context, t => makeChange(t, sourceFile, span.start)),
@@ -41,37 +41,18 @@ namespace ts.codefix {
4141
getAllCodeActions: context => {
4242
const seenLines = createMap<true>();
4343
return codeFixAll(context, errorCodes, (changes, diag) => {
44-
if (isValidSuppressLocation(diag.file!, diag.start!)) {
44+
if (textChanges.isValidLocationToAddComment(diag.file!, diag.start!)) {
4545
makeChange(changes, diag.file!, diag.start!, seenLines);
4646
}
4747
});
4848
},
4949
});
5050

51-
function isValidSuppressLocation(sourceFile: SourceFile, position: number) {
52-
return !isInComment(sourceFile, position) && !isInString(sourceFile, position) && !isInTemplateString(sourceFile, position);
53-
}
54-
5551
function makeChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, seenLines?: Map<true>) {
5652
const { line: lineNumber } = getLineAndCharacterOfPosition(sourceFile, position);
57-
5853
// Only need to add `// @ts-ignore` for a line once.
59-
if (seenLines && !addToSeen(seenLines, lineNumber)) {
60-
return;
54+
if (!seenLines || addToSeen(seenLines, lineNumber)) {
55+
changes.insertCommentBeforeLine(sourceFile, lineNumber, position, " @ts-ignore");
6156
}
62-
63-
const lineStartPosition = getStartPositionOfLine(lineNumber, sourceFile);
64-
const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
65-
66-
// First try to see if we can put the '// @ts-ignore' on the previous line.
67-
// We need to make sure that we are not in the middle of a string literal or a comment.
68-
// If so, we do not want to separate the node from its comment if we can.
69-
// Otherwise, add an extra new line immediately before the error span.
70-
const insertAtLineStart = isValidSuppressLocation(sourceFile, startPosition);
71-
72-
const token = getTouchingToken(sourceFile, insertAtLineStart ? startPosition : position, /*includeJsDocComment*/ false);
73-
const clone = setStartsOnNewLine(getSynthesizedDeepClone(token), true);
74-
addSyntheticLeadingComment(clone, SyntaxKind.SingleLineCommentTrivia, " @ts-ignore");
75-
changes.replaceNode(sourceFile, token, clone, { preserveLeadingWhitespace: true, prefix: insertAtLineStart ? undefined : changes.newLineCharacter });
7657
}
7758
}

src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace ts.codefix {
2727
}
2828

2929
function doChanges(changes: textChanges.ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: ReadonlyArray<HeritageClause>): void {
30-
changes.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword), textChanges.useNonAdjustedPositions);
30+
changes.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword));
3131

3232
// If there is already an implements clause, replace the implements keyword with a comma.
3333
if (heritageClauses.length === 2 &&

src/services/codefixes/fixForgottenThisPropertyAccess.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ namespace ts.codefix {
3030
}
3131
// TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper
3232
suppressLeadingAndTrailingTrivia(token);
33-
changes.replaceNode(sourceFile, token, createPropertyAccess(createThis(), token), textChanges.useNonAdjustedPositions);
33+
changes.replaceNode(sourceFile, token, createPropertyAccess(createThis(), token));
3434
}
3535
}

src/services/codefixes/fixInvalidImportSyntax.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ namespace ts.codefix {
4242
}
4343

4444
function createAction(context: CodeFixContext, sourceFile: SourceFile, node: Node, replacement: Node): CodeAction {
45-
// TODO: GH#21246 Should be able to use `replaceNode`, but be sure to preserve comments (see `codeFixCalledES2015Import11.ts`)
46-
const changes = textChanges.ChangeTracker.with(context, t => t.replaceRange(sourceFile, { pos: node.getStart(), end: node.end }, replacement));
45+
const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, node, replacement));
4746
return {
4847
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Replace_import_with_0), [changes[0].textChanges[0].newText]),
4948
changes,

0 commit comments

Comments
 (0)