Skip to content

Commit 22b9e7a

Browse files
committed
Merge branch 'main' into fix-exact-optional-unassignable-properties
2 parents cdbe969 + f1ce0f5 commit 22b9e7a

21 files changed

+314
-64
lines changed

package-lock.json

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

src/compiler/binder.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1666,11 +1666,15 @@ namespace ts {
16661666
}
16671667

16681668
function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag) {
1669-
setParent(node.tagName, node);
1669+
bind(node.tagName);
16701670
if (node.kind !== SyntaxKind.JSDocEnumTag && node.fullName) {
1671+
// don't bind the type name yet; that's delayed until delayedBindJSDocTypedefTag
16711672
setParent(node.fullName, node);
16721673
setParentRecursive(node.fullName, /*incremental*/ false);
16731674
}
1675+
if (typeof node.comment !== "string") {
1676+
bindEach(node.comment);
1677+
}
16741678
}
16751679

16761680
function bindJSDocClassTag(node: JSDocClassTag) {

src/compiler/checker.ts

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ namespace ts {
555555
getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp),
556556
getExpandedParameters,
557557
hasEffectiveRestParameter,
558+
containsArgumentsReference,
558559
getConstantValue: nodeIn => {
559560
const node = getParseTreeNode(nodeIn, canHaveConstantValue);
560561
return node ? getConstantValue(node) : undefined;
@@ -16443,25 +16444,6 @@ namespace ts {
1644316444
(hasContextSensitiveParameters(node) || hasContextSensitiveReturnExpression(node));
1644416445
}
1644516446

16446-
function hasContextSensitiveParameters(node: FunctionLikeDeclaration) {
16447-
// Functions with type parameters are not context sensitive.
16448-
if (!node.typeParameters) {
16449-
// Functions with any parameters that lack type annotations are context sensitive.
16450-
if (some(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) {
16451-
return true;
16452-
}
16453-
if (node.kind !== SyntaxKind.ArrowFunction) {
16454-
// If the first parameter is not an explicit 'this' parameter, then the function has
16455-
// an implicit 'this' parameter which is subject to contextual typing.
16456-
const parameter = firstOrUndefined(node.parameters);
16457-
if (!(parameter && parameterIsThisKeyword(parameter))) {
16458-
return true;
16459-
}
16460-
}
16461-
}
16462-
return false;
16463-
}
16464-
1646516447
function hasContextSensitiveReturnExpression(node: FunctionLikeDeclaration) {
1646616448
// TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
1646716449
return !node.typeParameters && !getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body);

src/compiler/factory/nodeTests.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ namespace ts {
129129
return node.kind === SyntaxKind.StaticKeyword;
130130
}
131131

132+
/* @internal */
133+
export function isAbstractModifier(node: Node): node is AbstractKeyword {
134+
return node.kind === SyntaxKind.AbstractKeyword;
135+
}
136+
132137
/*@internal*/
133138
export function isSuperKeyword(node: Node): node is SuperExpression {
134139
return node.kind === SyntaxKind.SuperKeyword;

src/compiler/parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,8 @@ namespace ts {
530530
visitNode(cbNode, (node as JSDocTypedefTag).fullName) ||
531531
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined))
532532
: visitNode(cbNode, (node as JSDocTypedefTag).fullName) ||
533-
visitNode(cbNode, (node as JSDocTypedefTag).typeExpression)) ||
534-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
533+
visitNode(cbNode, (node as JSDocTypedefTag).typeExpression) ||
534+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined)));
535535
case SyntaxKind.JSDocCallbackTag:
536536
return visitNode(cbNode, (node as JSDocTag).tagName) ||
537537
visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||

src/compiler/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4205,6 +4205,8 @@ namespace ts {
42054205
/* @internal */ getResolvedSignatureForSignatureHelp(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
42064206
/* @internal */ getExpandedParameters(sig: Signature): readonly (readonly Symbol[])[];
42074207
/* @internal */ hasEffectiveRestParameter(sig: Signature): boolean;
4208+
/* @internal */ containsArgumentsReference(declaration: SignatureDeclaration): boolean;
4209+
42084210
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
42094211
isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined;
42104212
isUndefinedSymbol(symbol: Symbol): boolean;

src/compiler/utilities.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7343,4 +7343,23 @@ namespace ts {
73437343
return (parent as SourceFile).statements;
73447344
}
73457345
}
7346+
7347+
export function hasContextSensitiveParameters(node: FunctionLikeDeclaration) {
7348+
// Functions with type parameters are not context sensitive.
7349+
if (!node.typeParameters) {
7350+
// Functions with any parameters that lack type annotations are context sensitive.
7351+
if (some(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) {
7352+
return true;
7353+
}
7354+
if (node.kind !== SyntaxKind.ArrowFunction) {
7355+
// If the first parameter is not an explicit 'this' parameter, then the function has
7356+
// an implicit 'this' parameter which is subject to contextual typing.
7357+
const parameter = firstOrUndefined(node.parameters);
7358+
if (!(parameter && parameterIsThisKeyword(parameter))) {
7359+
return true;
7360+
}
7361+
}
7362+
}
7363+
return false;
7364+
}
73467365
}

src/services/classifier2020.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ namespace ts.classifier.v2020 {
7979
inJSXElement = false;
8080
}
8181

82-
if (isIdentifier(node) && !inJSXElement && !inImportClause(node)) {
82+
if (isIdentifier(node) && !inJSXElement && !inImportClause(node) && !isInfinityOrNaNString(node.escapedText)) {
8383
let symbol = typeChecker.getSymbolAtLocation(node);
8484
if (symbol) {
8585
if (symbol.flags & SymbolFlags.Alias) {
@@ -225,6 +225,10 @@ namespace ts.classifier.v2020 {
225225
return (isQualifiedName(node.parent) && node.parent.right === node) || (isPropertyAccessExpression(node.parent) && node.parent.name === node);
226226
}
227227

228+
function isInfinityOrNaNString(name: __String): boolean {
229+
return name === "Infinity" || name === "NaN";
230+
}
231+
228232
const tokenFromDeclarationMapping = new Map<SyntaxKind, TokenType>([
229233
[SyntaxKind.VariableDeclaration, TokenType.variable],
230234
[SyntaxKind.Parameter, TokenType.parameter],

src/services/codefixes/fixOverrideModifier.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,13 @@ namespace ts.codefix {
8989
const classElement = findContainerClassElementLike(sourceFile, pos);
9090
const modifiers = classElement.modifiers || emptyArray;
9191
const staticModifier = find(modifiers, isStaticModifier);
92+
const abstractModifier = find(modifiers, isAbstractModifier);
9293
const accessibilityModifier = find(modifiers, m => isAccessibilityModifier(m.kind));
93-
const modifierPos = staticModifier ? staticModifier.end :
94+
const modifierPos = abstractModifier ? abstractModifier.end :
95+
staticModifier ? staticModifier.end :
9496
accessibilityModifier ? accessibilityModifier.end :
9597
classElement.decorators ? skipTrivia(sourceFile.text, classElement.decorators.end) : classElement.getStart(sourceFile);
96-
const options = accessibilityModifier || staticModifier ? { prefix: " " } : { suffix: " " };
98+
const options = accessibilityModifier || staticModifier || abstractModifier ? { prefix: " " } : { suffix: " " };
9799
changeTracker.insertModifierAt(sourceFile, modifierPos, SyntaxKind.OverrideKeyword, options);
98100
}
99101

src/services/inlayHints.ts

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ namespace ts.InlayHints {
6464
visitCallOrNewExpression(node);
6565
}
6666
else {
67-
if (preferences.includeInlayFunctionParameterTypeHints && isFunctionExpressionLike(node)) {
68-
visitFunctionExpressionLikeForParameterType(node);
67+
if (preferences.includeInlayFunctionParameterTypeHints && isFunctionLikeDeclaration(node) && hasContextSensitiveParameters(node)) {
68+
visitFunctionLikeForParameterType(node);
6969
}
7070
if (preferences.includeInlayFunctionLikeReturnTypeHints && isSignatureSupportingReturnAnnotation(node)) {
7171
visitFunctionDeclarationLikeForReturnType(node);
@@ -78,10 +78,6 @@ namespace ts.InlayHints {
7878
return isArrowFunction(node) || isFunctionExpression(node) || isFunctionDeclaration(node) || isMethodDeclaration(node) || isGetAccessorDeclaration(node);
7979
}
8080

81-
function isFunctionExpressionLike(node: Node): node is ArrowFunction | FunctionExpression {
82-
return isArrowFunction(node) || isFunctionExpression(node);
83-
}
84-
8581
function addParameterHints(text: string, position: number, isFirstVariadicArgument: boolean) {
8682
result.push({
8783
text: `${isFirstVariadicArgument ? "..." : ""}${truncation(text, maxHintsLength)}:`,
@@ -207,7 +203,7 @@ namespace ts.InlayHints {
207203
}
208204

209205
function isHintableExpression(node: Node) {
210-
return isLiteralExpression(node) || isBooleanLiteral(node) || isFunctionExpressionLike(node) || isObjectLiteralExpression(node) || isArrayLiteralExpression(node);
206+
return isLiteralExpression(node) || isBooleanLiteral(node) || isArrowFunction(node) || isFunctionExpression(node) || isObjectLiteralExpression(node) || isArrayLiteralExpression(node);
211207
}
212208

213209
function visitFunctionDeclarationLikeForReturnType(decl: FunctionDeclaration | ArrowFunction | FunctionExpression | MethodDeclaration | GetAccessorDeclaration) {
@@ -248,24 +244,14 @@ namespace ts.InlayHints {
248244
return decl.parameters.end;
249245
}
250246

251-
function visitFunctionExpressionLikeForParameterType(expr: ArrowFunction | FunctionExpression) {
252-
if (!expr.parameters.length || expr.parameters.every(param => !!getEffectiveTypeAnnotationNode(param))) {
253-
return;
254-
}
255-
256-
const contextualType = checker.getContextualType(expr);
257-
if (!contextualType) {
258-
return;
259-
}
260-
261-
const signatures = checker.getSignaturesOfType(contextualType, SignatureKind.Call);
262-
const signature = firstOrUndefined(signatures);
247+
function visitFunctionLikeForParameterType(node: FunctionLikeDeclaration) {
248+
const signature = checker.getSignatureFromDeclaration(node);
263249
if (!signature) {
264250
return;
265251
}
266252

267-
for (let i = 0; i < expr.parameters.length && i < signature.parameters.length; ++i) {
268-
const param = expr.parameters[i];
253+
for (let i = 0; i < node.parameters.length && i < signature.parameters.length; ++i) {
254+
const param = node.parameters[i];
269255
const effectiveTypeAnnotation = getEffectiveTypeAnnotationNode(param);
270256

271257
if (effectiveTypeAnnotation) {

src/services/refactors/convertArrowFunctionOrFunctionExpression.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression {
141141
const token = getTokenAtPosition(file, startPosition);
142142
const typeChecker = program.getTypeChecker();
143143
const func = tryGetFunctionFromVariableDeclaration(file, typeChecker, token.parent);
144-
if (func && !containingThis(func.body)) {
144+
if (func && !containingThis(func.body) && !typeChecker.containsArgumentsReference(func)) {
145145
return { selectedVariableDeclaration: true, func };
146146
}
147147

@@ -150,7 +150,8 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression {
150150
maybeFunc &&
151151
(isFunctionExpression(maybeFunc) || isArrowFunction(maybeFunc)) &&
152152
!rangeContainsRange(maybeFunc.body, token) &&
153-
!containingThis(maybeFunc.body)
153+
!containingThis(maybeFunc.body) &&
154+
!typeChecker.containsArgumentsReference(maybeFunc)
154155
) {
155156
if (isFunctionExpression(maybeFunc) && isFunctionReferencedInFile(file, typeChecker, maybeFunc)) return undefined;
156157
return { selectedVariableDeclaration: false, func: maybeFunc };
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
[
2+
{
3+
"marker": {
4+
"fileName": "/tests/cases/fourslash/quickInfoLink2.js",
5+
"position": 39,
6+
"name": ""
7+
},
8+
"quickInfo": {
9+
"kind": "type",
10+
"kindModifiers": "",
11+
"textSpan": {
12+
"start": 16,
13+
"length": 23
14+
},
15+
"displayParts": [
16+
{
17+
"text": "type",
18+
"kind": "keyword"
19+
},
20+
{
21+
"text": " ",
22+
"kind": "space"
23+
},
24+
{
25+
"text": "AdditionalWallabyConfig",
26+
"kind": "aliasName"
27+
},
28+
{
29+
"text": " ",
30+
"kind": "space"
31+
},
32+
{
33+
"text": "=",
34+
"kind": "operator"
35+
},
36+
{
37+
"text": " ",
38+
"kind": "space"
39+
},
40+
{
41+
"text": "{",
42+
"kind": "punctuation"
43+
},
44+
{
45+
"text": "\n",
46+
"kind": "lineBreak"
47+
},
48+
{
49+
"text": " ",
50+
"kind": "space"
51+
},
52+
{
53+
"text": "autoDetect",
54+
"kind": "propertyName"
55+
},
56+
{
57+
"text": ":",
58+
"kind": "punctuation"
59+
},
60+
{
61+
"text": " ",
62+
"kind": "space"
63+
},
64+
{
65+
"text": "boolean",
66+
"kind": "keyword"
67+
},
68+
{
69+
"text": ";",
70+
"kind": "punctuation"
71+
},
72+
{
73+
"text": "\n",
74+
"kind": "lineBreak"
75+
},
76+
{
77+
"text": "}",
78+
"kind": "punctuation"
79+
}
80+
],
81+
"documentation": [
82+
{
83+
"text": "Additional valid Wallaby config properties\nthat aren't defined in ",
84+
"kind": "text"
85+
},
86+
{
87+
"text": "{@link ",
88+
"kind": "link"
89+
},
90+
{
91+
"text": "IWallabyConfig ",
92+
"kind": "linkText"
93+
},
94+
{
95+
"text": "}",
96+
"kind": "link"
97+
},
98+
{
99+
"text": ".",
100+
"kind": "text"
101+
}
102+
]
103+
}
104+
}
105+
]

tests/cases/fourslash/codeFixOverrideModifier12.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111

1212
verify.codeFix({
1313
description: "Add 'override' modifier",
14-
newRangeContent: "override abstract bar() {}",
14+
newRangeContent: "abstract override bar() {}",
1515
index: 0
1616
})

0 commit comments

Comments
 (0)