Skip to content

Commit 34d675a

Browse files
committed
Merge remote-tracking branch 'origin/main' into intra-inference-in-reverse-mapped-types
2 parents fae5ae6 + 1a8c7ae commit 34d675a

39 files changed

+787
-39
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26578,7 +26578,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2657826578
if (container && container !== flowContainer &&
2657926579
reference.kind !== SyntaxKind.PropertyAccessExpression &&
2658026580
reference.kind !== SyntaxKind.ElementAccessExpression &&
26581-
reference.kind !== SyntaxKind.ThisKeyword) {
26581+
!(reference.kind === SyntaxKind.ThisKeyword && container.kind !== SyntaxKind.ArrowFunction)
26582+
) {
2658226583
flow = container.flowNode!;
2658326584
continue;
2658426585
}
@@ -37831,7 +37832,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3783137832
if (getIsolatedModules(compilerOptions)) {
3783237833
Debug.assert(!!(type.symbol.flags & SymbolFlags.ConstEnum));
3783337834
const constEnumDeclaration = type.symbol.valueDeclaration as EnumDeclaration;
37834-
if (constEnumDeclaration.flags & NodeFlags.Ambient) {
37835+
if (constEnumDeclaration.flags & NodeFlags.Ambient && !isValidTypeOnlyAliasUseSite(node)) {
3783537836
error(node, Diagnostics.Cannot_access_ambient_const_enums_when_0_is_enabled, isolatedModulesLikeFlagName);
3783637837
}
3783737838
}

src/harness/client.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
ImplementationLocation,
3737
InlayHint,
3838
InlayHintKind,
39+
InteractiveRefactorArguments,
3940
isString,
4041
JSDocTagInfo,
4142
LanguageService,
@@ -52,6 +53,7 @@ import {
5253
Program,
5354
QuickInfo,
5455
RefactorEditInfo,
56+
RefactorTriggerReason,
5557
ReferencedSymbol,
5658
ReferenceEntry,
5759
RenameInfo,
@@ -787,11 +789,25 @@ export class SessionClient implements LanguageService {
787789
return { file, line, offset, endLine, endOffset };
788790
}
789791

790-
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange): ApplicableRefactorInfo[] {
791-
const args = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName);
792-
792+
getApplicableRefactors(
793+
fileName: string,
794+
positionOrRange: number | TextRange,
795+
preferences: UserPreferences | undefined,
796+
triggerReason?: RefactorTriggerReason,
797+
kind?: string,
798+
includeInteractiveActions?: boolean): ApplicableRefactorInfo[] {
799+
if (preferences) { // Temporarily set preferences
800+
this.configure(preferences);
801+
}
802+
const args: protocol.GetApplicableRefactorsRequestArgs = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName);
803+
args.triggerReason = triggerReason;
804+
args.kind = kind;
805+
args.includeInteractiveActions = includeInteractiveActions;
793806
const request = this.processRequest<protocol.GetApplicableRefactorsRequest>(protocol.CommandTypes.GetApplicableRefactors, args);
794807
const response = this.processResponse<protocol.GetApplicableRefactorsResponse>(request);
808+
if (preferences) { // Restore preferences
809+
this.configure(this.preferences || {});
810+
}
795811
return response.body!; // TODO: GH#18217
796812
}
797813

@@ -808,11 +824,17 @@ export class SessionClient implements LanguageService {
808824
_formatOptions: FormatCodeSettings,
809825
positionOrRange: number | TextRange,
810826
refactorName: string,
811-
actionName: string): RefactorEditInfo {
812-
813-
const args = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName) as protocol.GetEditsForRefactorRequestArgs;
827+
actionName: string,
828+
preferences: UserPreferences | undefined,
829+
interactiveRefactorArguments?: InteractiveRefactorArguments): RefactorEditInfo {
830+
if (preferences) { // Temporarily set preferences
831+
this.configure(preferences);
832+
}
833+
const args =
834+
this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName) as protocol.GetEditsForRefactorRequestArgs;
814835
args.refactor = refactorName;
815836
args.action = actionName;
837+
args.interactiveRefactorArguments = interactiveRefactorArguments;
816838

817839
const request = this.processRequest<protocol.GetEditsForRefactorRequest>(protocol.CommandTypes.GetEditsForRefactor, args);
818840
const response = this.processResponse<protocol.GetEditsForRefactorResponse>(request);
@@ -829,6 +851,10 @@ export class SessionClient implements LanguageService {
829851
renameLocation = this.lineOffsetToPosition(renameFilename, response.body.renameLocation!);
830852
}
831853

854+
if (preferences) { // Restore preferences
855+
this.configure(this.preferences || {});
856+
}
857+
832858
return {
833859
edits,
834860
renameFilename,

src/services/findAllReferences.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ import {
198198
nodeSeenTracker,
199199
NumericLiteral,
200200
ObjectLiteralExpression,
201+
or,
201202
ParameterDeclaration,
202203
ParenthesizedExpression,
203204
Path,
@@ -2177,9 +2178,9 @@ export namespace Core {
21772178
}
21782179

21792180
// Check if the node is within an extends or implements clause
2180-
const containingClass = getContainingClassIfInHeritageClause(refNode);
2181-
if (containingClass) {
2182-
addReference(containingClass);
2181+
const containingNode = getContainingNodeIfInHeritageClause(refNode);
2182+
if (containingNode) {
2183+
addReference(containingNode);
21832184
return;
21842185
}
21852186

@@ -2212,9 +2213,9 @@ export namespace Core {
22122213
}
22132214
}
22142215

2215-
function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration | InterfaceDeclaration | undefined {
2216-
return isIdentifier(node) || isPropertyAccessExpression(node) ? getContainingClassIfInHeritageClause(node.parent)
2217-
: isExpressionWithTypeArguments(node) ? tryCast(node.parent.parent, isClassLike) : undefined;
2216+
function getContainingNodeIfInHeritageClause(node: Node): ClassLikeDeclaration | InterfaceDeclaration | undefined {
2217+
return isIdentifier(node) || isPropertyAccessExpression(node) ? getContainingNodeIfInHeritageClause(node.parent)
2218+
: isExpressionWithTypeArguments(node) ? tryCast(node.parent.parent, or(isClassLike, isInterfaceDeclaration)) : undefined;
22182219
}
22192220

22202221
/**

src/services/jsDoc.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,7 @@ export function getDocCommentTemplateAtPosition(newLine: string, sourceFile: Sou
492492
// * if the caret was directly in front of the object, then we add an extra line and indentation.
493493
const openComment = "/**";
494494
const closeComment = " */";
495-
496-
// If any of the existing jsDoc has tags, ignore adding new ones.
497-
const hasTag = (commentOwnerJsDoc || []).some(jsDoc => !!jsDoc.tags);
495+
const hasTag = length(getJSDocTags(commentOwner)) > 0;
498496

499497
if (tags && !hasTag) {
500498
const preamble = openComment + newLine + indentationStr + " * ";

src/services/refactors/convertStringOrTemplateLiteral.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ function getEditsForToTemplateLiteral(context: RefactorContext, node: Node) {
122122
}
123123

124124
function isNotEqualsOperator(node: BinaryExpression) {
125-
return node.operatorToken.kind !== SyntaxKind.EqualsToken;
125+
return !(node.operatorToken.kind === SyntaxKind.EqualsToken || node.operatorToken.kind === SyntaxKind.PlusEqualsToken);
126126
}
127127

128128
function getParentBinaryExpression(expr: Node) {

src/services/refactors/moveToFile.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
find,
3636
FindAllReferences,
3737
findIndex,
38+
findLastIndex,
3839
firstDefined,
3940
flatMap,
4041
forEachKey,
@@ -51,6 +52,7 @@ import {
5152
getRangesWhere,
5253
getRefactorContextSpan,
5354
getRelativePathFromFile,
55+
getSourceFileOfNode,
5456
getSynthesizedDeepClone,
5557
getUniqueName,
5658
hasJSFileExtension,
@@ -69,6 +71,7 @@ import {
6971
isDeclarationName,
7072
isExpressionStatement,
7173
isExternalModuleReference,
74+
isFunctionLikeDeclaration,
7275
isIdentifier,
7376
isImportDeclaration,
7477
isImportEqualsDeclaration,
@@ -80,6 +83,7 @@ import {
8083
isPropertyAssignment,
8184
isRequireCall,
8285
isSourceFile,
86+
isStatement,
8387
isStringLiteral,
8488
isStringLiteralLike,
8589
isValidTypeOnlyAliasUseSite,
@@ -176,8 +180,8 @@ registerRefactor(refactorNameForMoveToFile, {
176180
function doChange(context: RefactorContext, oldFile: SourceFile, targetFile: string, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences): void {
177181
const checker = program.getTypeChecker();
178182
const usage = getUsageInfo(oldFile, toMove.all, checker);
179-
//For a new file or an existing blank target file
180-
if (!host.fileExists(targetFile) || host.fileExists(targetFile) && program.getSourceFile(targetFile)?.statements.length === 0) {
183+
//For a new file
184+
if (!host.fileExists(targetFile)) {
181185
changes.createNewFile(oldFile, targetFile, getNewStatementsAndRemoveFromOldFile(oldFile, targetFile, usage, changes, toMove, program, host, preferences));
182186
addNewFileToTsconfig(program, changes, oldFile.fileName, targetFile, hostGetCanonicalFileName(host));
183187
}
@@ -189,7 +193,15 @@ function doChange(context: RefactorContext, oldFile: SourceFile, targetFile: str
189193
}
190194

191195
function getNewStatementsAndRemoveFromOldFile(
192-
oldFile: SourceFile, targetFile: string | SourceFile, usage: UsageInfo, changes: textChanges.ChangeTracker, toMove: ToMove, program: Program, host: LanguageServiceHost, preferences: UserPreferences, importAdder?: codefix.ImportAdder
196+
oldFile: SourceFile,
197+
targetFile: string | SourceFile,
198+
usage: UsageInfo,
199+
changes: textChanges.ChangeTracker,
200+
toMove: ToMove,
201+
program: Program,
202+
host: LanguageServiceHost,
203+
preferences: UserPreferences,
204+
importAdder?: codefix.ImportAdder
193205
) {
194206
const checker = program.getTypeChecker();
195207
const prologueDirectives = takeWhile(oldFile.statements, isPrologueDirective);
@@ -218,6 +230,9 @@ function getNewStatementsAndRemoveFromOldFile(
218230
if (targetFile.statements.length > 0) {
219231
changes.insertNodesAfter(targetFile, targetFile.statements[targetFile.statements.length - 1], body);
220232
}
233+
else {
234+
changes.insertNodesAtEndOfFile(targetFile, body, /*blankLineBetween*/ false);
235+
}
221236
if (imports.length > 0) {
222237
insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences);
223238
}
@@ -890,6 +905,11 @@ function getRangeToMove(context: RefactorContext): RangeToMove | undefined {
890905
return { toMove: [statements[startNodeIndex]], afterLast: statements[startNodeIndex + 1] };
891906
}
892907

908+
const overloadRangeToMove = getOverloadRangeToMove(file, startStatement);
909+
if (overloadRangeToMove) {
910+
return overloadRangeToMove;
911+
}
912+
893913
// Can't only partially include the start node or be partially into the next node
894914
if (range.pos > startStatement.getStart(file)) return undefined;
895915
const afterEndNodeIndex = findIndex(statements, s => s.end > range.end, startNodeIndex);
@@ -1109,4 +1129,16 @@ function isNonVariableTopLevelDeclaration(node: Node): node is NonVariableTopLev
11091129
}
11101130
}
11111131

1112-
1132+
function getOverloadRangeToMove(sourceFile: SourceFile, statement: Statement) {
1133+
if (isFunctionLikeDeclaration(statement)) {
1134+
const declarations = statement.symbol.declarations;
1135+
if (declarations === undefined || length(declarations) <= 1 || !contains(declarations, statement)) {
1136+
return undefined;
1137+
}
1138+
const lastDecl = declarations[length(declarations) - 1];
1139+
const statementsToMove = mapDefined(declarations, d => getSourceFileOfNode(d) === sourceFile && isStatement(d) ? d : undefined);
1140+
const end = findLastIndex(sourceFile.statements, s => s.end > lastDecl.end);
1141+
return { toMove: statementsToMove, afterLast: end >= 0 ? sourceFile.statements[end] : undefined };
1142+
}
1143+
return undefined;
1144+
}

src/services/textChanges.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,25 @@ export class ChangeTracker {
631631
}
632632
}
633633

634+
public insertNodesAtEndOfFile(
635+
sourceFile: SourceFile,
636+
newNodes: readonly Statement[],
637+
blankLineBetween: boolean): void {
638+
this.insertAtEndOfFile(sourceFile, newNodes, blankLineBetween);
639+
}
640+
641+
private insertAtEndOfFile(
642+
sourceFile: SourceFile,
643+
insert: readonly Statement[],
644+
blankLineBetween: boolean): void {
645+
const pos = sourceFile.end + 1;
646+
const options = {
647+
prefix: this.newLineCharacter,
648+
suffix: this.newLineCharacter + (blankLineBetween ? this.newLineCharacter : ""),
649+
};
650+
this.insertNodesAt(sourceFile, pos, insert, options);
651+
}
652+
634653
private insertStatementsInNewFile(fileName: string, statements: readonly (Statement | SyntaxKind.NewLineTrivia)[], oldFile?: SourceFile): void {
635654
if (!this.newFileChanges) {
636655
this.newFileChanges = createMultiMap<string, NewFileInsertion>();

src/services/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ export interface LanguageService {
652652
* arguments for any interactive action before offering it.
653653
*/
654654
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string, includeInteractiveActions?: boolean): ApplicableRefactorInfo[];
655-
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, includeInteractiveActions?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
655+
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, interactiveRefactorArguments?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
656656
getMoveToRefactoringFileSuggestions(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string): { newFileName: string, files: string[] };
657657
organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): readonly FileTextChanges[];
658658
getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): readonly FileTextChanges[];

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10196,7 +10196,7 @@ declare namespace ts {
1019610196
* arguments for any interactive action before offering it.
1019710197
*/
1019810198
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string, includeInteractiveActions?: boolean): ApplicableRefactorInfo[];
10199-
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, includeInteractiveActions?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
10199+
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, interactiveRefactorArguments?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
1020010200
getMoveToRefactoringFileSuggestions(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string): {
1020110201
newFileName: string;
1020210202
files: string[];

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6227,7 +6227,7 @@ declare namespace ts {
62276227
* arguments for any interactive action before offering it.
62286228
*/
62296229
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string, includeInteractiveActions?: boolean): ApplicableRefactorInfo[];
6230-
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, includeInteractiveActions?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
6230+
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, interactiveRefactorArguments?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
62316231
getMoveToRefactoringFileSuggestions(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string): {
62326232
newFileName: string;
62336233
files: string[];

tests/baselines/reference/goToImplementationInterface_00.baseline.jsonc

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,44 @@
44
// hello: () => void
55
// }
66
//
7-
// interface Baz extends Foo {}
7+
// <|interface [|{| defId: 0 |}Baz|] extends Foo {}|>
88
//
9-
// var bar: Foo = [|{| defId: 0 |}{ hello: helloImpl /**0*/ }|];
10-
// var baz: Foo[] = [|{| defId: 1 |}[{ hello: helloImpl /**4*/ }]|];
9+
// var bar: Foo = [|{| defId: 1 |}{ hello: helloImpl /**0*/ }|];
10+
// var baz: Foo[] = [|{| defId: 2 |}[{ hello: helloImpl /**4*/ }]|];
1111
//
1212
// function helloImpl () {}
1313
//
14-
// function whatever(x: Foo = [|{| defId: 2 |}{ hello() {/**1*/} }|] ) {
14+
// function whatever(x: Foo = [|{| defId: 3 |}{ hello() {/**1*/} }|] ) {
1515
// }
1616
//
1717
// class Bar {
18-
// x: Foo = [|{| defId: 3 |}{ hello() {} }|]
18+
// x: Foo = [|{| defId: 4 |}{ hello() {} }|]
1919
//
20-
// constructor(public f: Foo = [|{| defId: 4 |}{ hello() {/**3*/} }|] ) {}
20+
// constructor(public f: Foo = [|{| defId: 5 |}{ hello() {/**3*/} }|] ) {}
2121
// }
2222

2323
// === Details ===
2424
[
2525
{
2626
"defId": 0,
27+
"displayParts": [
28+
{
29+
"text": "interface",
30+
"kind": "keyword"
31+
},
32+
{
33+
"text": " ",
34+
"kind": "space"
35+
},
36+
{
37+
"text": "Baz",
38+
"kind": "interfaceName"
39+
}
40+
],
41+
"kind": "interface"
42+
},
43+
{
44+
"defId": 1,
2745
"kind": "interface",
2846
"displayParts": [
2947
{
@@ -41,12 +59,12 @@
4159
]
4260
},
4361
{
44-
"defId": 1,
62+
"defId": 2,
4563
"kind": "",
4664
"displayParts": []
4765
},
4866
{
49-
"defId": 2,
67+
"defId": 3,
5068
"kind": "interface",
5169
"displayParts": [
5270
{
@@ -64,7 +82,7 @@
6482
]
6583
},
6684
{
67-
"defId": 3,
85+
"defId": 4,
6886
"kind": "interface",
6987
"displayParts": [
7088
{
@@ -82,7 +100,7 @@
82100
]
83101
},
84102
{
85-
"defId": 4,
103+
"defId": 5,
86104
"kind": "interface",
87105
"displayParts": [
88106
{

0 commit comments

Comments
 (0)