Skip to content

Commit 257da12

Browse files
Merge remote-tracking branch 'origin/main' into release-4.4
2 parents 59225a6 + 5c8d763 commit 257da12

File tree

29 files changed

+1115
-67
lines changed

29 files changed

+1115
-67
lines changed

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/eslint/rules/boolean-trivia.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export = createRule({
2323
const sourceCodeText = sourceCode.getText();
2424

2525
const isSetOrAssert = (name: string): boolean => name.startsWith("set") || name.startsWith("assert");
26-
const isTrivia = (node: TSESTree.CallExpressionArgument): boolean => {
26+
const isTrivia = (node: TSESTree.Node): boolean => {
2727
if (node.type === AST_NODE_TYPES.Identifier) {
2828
return node.name === "undefined";
2929
}
@@ -69,7 +69,7 @@ export = createRule({
6969
return false;
7070
};
7171

72-
const checkArg = (node: TSESTree.CallExpressionArgument): void => {
72+
const checkArg = (node: TSESTree.Node): void => {
7373
if (!isTrivia(node)) {
7474
return;
7575
}

src/compiler/checker.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12106,7 +12106,7 @@ namespace ts {
1210612106
}
1210712107

1210812108
function getApplicableIndexInfoForName(type: Type, name: __String): IndexInfo | undefined {
12109-
return getApplicableIndexInfo(type, getStringLiteralType(unescapeLeadingUnderscores(name)));
12109+
return getApplicableIndexInfo(type, isLateBoundName(name) ? esSymbolType : getStringLiteralType(unescapeLeadingUnderscores(name)));
1211012110
}
1211112111

1211212112
// Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
@@ -27121,8 +27121,12 @@ namespace ts {
2712127121
*/
2712227122
function isKnownProperty(targetType: Type, name: __String, isComparingJsxAttributes: boolean): boolean {
2712327123
if (targetType.flags & TypeFlags.Object) {
27124+
// For backwards compatibility a symbol-named property is satisfied by a string index signature. This
27125+
// is incorrect and inconsistent with element access expressions, where it is an error, so eventually
27126+
// we should remove this exception.
2712427127
if (getPropertyOfObjectType(targetType, name) ||
2712527128
getApplicableIndexInfoForName(targetType, name) ||
27129+
isLateBoundName(name) && getIndexInfoOfType(targetType, stringType) ||
2712627130
isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
2712727131
// For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
2712827132
return true;
@@ -28724,8 +28728,10 @@ namespace ts {
2872428728
* Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise.
2872528729
*/
2872628730
function getThisArgumentOfCall(node: CallLikeExpression): LeftHandSideExpression | undefined {
28727-
if (node.kind === SyntaxKind.CallExpression) {
28728-
const callee = skipOuterExpressions(node.expression);
28731+
const expression = node.kind === SyntaxKind.CallExpression ? node.expression :
28732+
node.kind === SyntaxKind.TaggedTemplateExpression ? node.tag : undefined;
28733+
if (expression) {
28734+
const callee = skipOuterExpressions(expression);
2872928735
if (isAccessExpression(callee)) {
2873028736
return callee.expression;
2873128737
}
@@ -31403,8 +31409,9 @@ namespace ts {
3140331409
}
3140431410

3140531411
function checkDeleteExpressionMustBeOptional(expr: AccessExpression, type: Type) {
31406-
const AnyOrUnknownOrNeverFlags = TypeFlags.AnyOrUnknown | TypeFlags.Never;
31407-
if (strictNullChecks && !(type.flags & AnyOrUnknownOrNeverFlags) && !(getFalsyFlags(type) & TypeFlags.Undefined)) {
31412+
if (strictNullChecks &&
31413+
!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Never)) &&
31414+
!(exactOptionalPropertyTypes ? 0 : getFalsyFlags(type) & TypeFlags.Undefined)) {
3140831415
error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_optional);
3140931416
}
3141031417
}

src/server/scriptVersionCache.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,8 @@ namespace ts.server {
6767
}
6868
const lm = LineIndex.linesFromText(insertedText);
6969
const lines = lm.lines;
70-
if (lines.length > 1) {
71-
if (lines[lines.length - 1] === "") {
72-
lines.pop();
73-
}
70+
if (lines.length > 1 && lines[lines.length - 1] === "") {
71+
lines.pop();
7472
}
7573
let branchParent: LineNode | undefined;
7674
let lastZeroCount: LineCollection | undefined;
@@ -683,8 +681,12 @@ namespace ts.server {
683681
}
684682

685683
// Skipped all children
686-
const { leaf } = this.lineNumberToInfo(this.lineCount(), 0);
687-
return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf ? leaf.charCount() : 0, lineText: undefined };
684+
const lineCount = this.lineCount();
685+
if (lineCount === 0) { // it's empty! (and lineNumberToInfo expects a one-based line)
686+
return { oneBasedLine: 1, zeroBasedColumn: 0, lineText: undefined };
687+
}
688+
const leaf = Debug.checkDefined(this.lineNumberToInfo(lineCount, 0).leaf);
689+
return { oneBasedLine: lineCount, zeroBasedColumn: leaf.charCount(), lineText: undefined };
688690
}
689691

690692
/**

src/testRunner/compilerRunner.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ namespace Harness {
136136
"skipDefaultLibCheck",
137137
"preserveConstEnums",
138138
"skipLibCheck",
139+
"exactOptionalPropertyTypes"
139140
];
140141
private fileName: string;
141142
private justName: string;

src/testRunner/unittests/tsserver/versionCache.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ var q:Point=<Point>p;`;
5252
assert.deepEqual(lineIndex.positionToLineOffset(0), { line: 1, offset: 1 });
5353
});
5454

55+
it("handles emptying whole file (GH#44518)", () => {
56+
// See below for the main thing that this tests; it would be better to have a test
57+
// that uses `ScriptInfo.positionToLineOffset` but I couldn't find away to do that
58+
const { lines } = server.LineIndex.linesFromText("function foo() {\n\ndsa\n\n}\n\nfo(dsa\n\n\n ");
59+
const lineIndex = new server.LineIndex();
60+
lineIndex.load(lines);
61+
const snapshot = lineIndex.edit(0, 39);
62+
assert.equal(snapshot.getText(0, snapshot.getLength()), "");
63+
// line must always be >=1, otherwise the failIfInvalidLocation(location) assertion in ScriptInfo.positionToLineOffset will fail
64+
assert.deepEqual(snapshot.positionToLineOffset(0), { line: 1, offset: 1 });
65+
});
66+
5567
it(`change 9 1 0 1 {"y"}`, () => {
5668
validateEditAtLineCharIndex(9, 1, 0, "y");
5769
});

tests/baselines/reference/deleteExpressionMustBeOptional(strict=false).errors.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ tests/cases/compiler/deleteExpressionMustBeOptional.ts(34,10): error TS2339: Pro
4343
delete a.b
4444

4545
delete b.a
46-
delete b.b
46+
delete b.b
47+

tests/baselines/reference/deleteExpressionMustBeOptional(strict=false).js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ delete a.a
3838
delete a.b
3939

4040
delete b.a
41-
delete b.b
41+
delete b.b
42+
4243

4344
//// [deleteExpressionMustBeOptional.js]
4445
delete f.a;

tests/baselines/reference/deleteExpressionMustBeOptional(strict=true).errors.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@ tests/cases/compiler/deleteExpressionMustBeOptional.ts(34,10): error TS2339: Pro
4949
delete a.b
5050

5151
delete b.a
52-
delete b.b
52+
delete b.b
53+

tests/baselines/reference/deleteExpressionMustBeOptional(strict=true).js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ delete a.a
3838
delete a.b
3939

4040
delete b.a
41-
delete b.b
41+
delete b.b
42+
4243

4344
//// [deleteExpressionMustBeOptional.js]
4445
"use strict";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts(25,8): error TS2790: The operand of a 'delete' operator must be optional.
2+
tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts(27,8): error TS2790: The operand of a 'delete' operator must be optional.
3+
tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts(34,10): error TS2339: Property 'j' does not exist on type 'Foo'.
4+
5+
6+
==== tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts (3 errors) ====
7+
interface Foo {
8+
a: number
9+
b: number | undefined
10+
c: number | null
11+
d?: number
12+
e: number | undefined | null
13+
f?: number | undefined | null
14+
g: unknown
15+
h: any
16+
i: never
17+
}
18+
19+
interface AA {
20+
[s: string]: number
21+
}
22+
23+
type BB = {
24+
[P in keyof any]: number
25+
}
26+
27+
declare const f: Foo
28+
declare const a: AA
29+
declare const b: BB
30+
31+
delete f.a
32+
~~~
33+
!!! error TS2790: The operand of a 'delete' operator must be optional.
34+
delete f.b
35+
delete f.c
36+
~~~
37+
!!! error TS2790: The operand of a 'delete' operator must be optional.
38+
delete f.d
39+
delete f.e
40+
delete f.f
41+
delete f.g
42+
delete f.h
43+
delete f.i
44+
delete f.j
45+
~
46+
!!! error TS2339: Property 'j' does not exist on type 'Foo'.
47+
48+
delete a.a
49+
delete a.b
50+
51+
delete b.a
52+
delete b.b
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//// [deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts]
2+
interface Foo {
3+
a: number
4+
b: number | undefined
5+
c: number | null
6+
d?: number
7+
e: number | undefined | null
8+
f?: number | undefined | null
9+
g: unknown
10+
h: any
11+
i: never
12+
}
13+
14+
interface AA {
15+
[s: string]: number
16+
}
17+
18+
type BB = {
19+
[P in keyof any]: number
20+
}
21+
22+
declare const f: Foo
23+
declare const a: AA
24+
declare const b: BB
25+
26+
delete f.a
27+
delete f.b
28+
delete f.c
29+
delete f.d
30+
delete f.e
31+
delete f.f
32+
delete f.g
33+
delete f.h
34+
delete f.i
35+
delete f.j
36+
37+
delete a.a
38+
delete a.b
39+
40+
delete b.a
41+
delete b.b
42+
43+
44+
//// [deleteExpressionMustBeOptional_exactOptionalPropertyTypes.js]
45+
delete f.a;
46+
delete f.b;
47+
delete f.c;
48+
delete f.d;
49+
delete f.e;
50+
delete f.f;
51+
delete f.g;
52+
delete f.h;
53+
delete f.i;
54+
delete f.j;
55+
delete a.a;
56+
delete a.b;
57+
delete b.a;
58+
delete b.b;

0 commit comments

Comments
 (0)