Add CopilotRelated command (#59963)

This commit is contained in:
Nathan Shively-Sanders
2024-09-26 16:10:41 -07:00
committed by GitHub
parent da1fb07db0
commit 52c59dbcbe
17 changed files with 298 additions and 1 deletions
+1
View File
@@ -800,6 +800,7 @@ export class SessionClient implements LanguageService {
}
mapCode: typeof notImplemented = notImplemented;
getImports: typeof notImplemented = notImplemented;
private createFileLocationOrRangeRequestArgs(positionOrRange: number | TextRange, fileName: string): protocol.FileLocationOrRangeRequestArgs {
return typeof positionOrRange === "number"
+22
View File
@@ -4638,6 +4638,28 @@ ${changes.join("\n// ---\n")}
${after}`;
this.baseline("mapCode", baseline, ".mapCode.ts");
}
public verifyGetImports(fileName: string, expectedImports: string[]): void {
const actualImports = this.languageService.getImports(fileName);
if (actualImports.length !== expectedImports.length) {
throw new Error(`Expected ${expectedImports.length} imports for ${fileName}, got ${actualImports.length}
Expected:
${expectedImports}
Actual:
${actualImports}
`);
}
for (let i = 0; i < expectedImports.length; i++) {
if (actualImports[i] !== expectedImports[i]) {
throw new Error(`Expected at ${fileName} index ${i}: ${expectedImports[i]}, got ${actualImports[i]}
Expected:
${expectedImports}
Actual:
${actualImports}
`);
}
}
}
}
function updateTextRangeForTextChanges({ pos, end }: ts.TextRange, textChanges: readonly ts.TextChange[]): ts.TextRange {
+9
View File
@@ -257,6 +257,10 @@ export class VerifyNegatable {
public baselineMapCode(ranges: FourSlash.Range[][], changes: string[] = []): void {
this.state.baselineMapCode(ranges, changes);
}
public getImports(fileName: string, imports: string[]): void {
return this.state.verifyGetImports(fileName, imports);
}
}
export interface CompletionsResult {
@@ -2047,3 +2051,8 @@ export interface RenameOptions {
readonly providePrefixAndSuffixTextForRename?: boolean;
readonly quotePreference?: "auto" | "double" | "single";
}
export interface VerifyGetImportsOptions {
fileName: string;
imports: string[];
}
+13
View File
@@ -202,6 +202,7 @@ export const enum CommandTypes {
ProvideInlayHints = "provideInlayHints",
WatchChange = "watchChange",
MapCode = "mapCode",
CopilotRelated = "copilotRelated",
}
/**
@@ -2406,6 +2407,18 @@ export interface MapCodeResponse extends Response {
body: readonly FileCodeEdits[];
}
export interface CopilotRelatedRequest extends FileRequest {
command: CommandTypes.CopilotRelated;
arguments: FileRequestArgs;
}
export interface CopilotRelatedItems {
relatedFiles: readonly string[];
}
export interface CopilotRelatedResponse extends Response {
body: CopilotRelatedItems;
}
/**
* Synchronous request for semantic diagnostics of one file.
*/
+12 -1
View File
@@ -937,6 +937,7 @@ const invalidPartialSemanticModeCommands: readonly protocol.CommandTypes[] = [
protocol.CommandTypes.ProvideCallHierarchyIncomingCalls,
protocol.CommandTypes.ProvideCallHierarchyOutgoingCalls,
protocol.CommandTypes.GetPasteEdits,
protocol.CommandTypes.CopilotRelated,
];
const invalidSyntacticModeCommands: readonly protocol.CommandTypes[] = [
@@ -2030,7 +2031,6 @@ export class Session<TMessage = string> implements EventSender {
};
});
}
private mapCode(args: protocol.MapCodeRequestArgs): protocol.FileCodeEdits[] {
const formatOptions = this.getHostFormatOptions();
const preferences = this.getHostPreferences();
@@ -2051,6 +2051,14 @@ export class Session<TMessage = string> implements EventSender {
return this.mapTextChangesToCodeEdits(changes);
}
private getCopilotRelatedInfo(args: protocol.FileRequestArgs): protocol.CopilotRelatedItems {
const { file, project } = this.getFileAndProject(args);
return {
relatedFiles: project.getLanguageService().getImports(file),
};
}
private setCompilerOptionsForInferredProjects(args: protocol.SetCompilerOptionsForInferredProjectsArgs): void {
this.projectService.setCompilerOptionsForInferredProjects(args.options, args.projectRootPath);
}
@@ -3791,6 +3799,9 @@ export class Session<TMessage = string> implements EventSender {
[protocol.CommandTypes.MapCode]: (request: protocol.MapCodeRequest) => {
return this.requiredResponse(this.mapCode(request.arguments));
},
[protocol.CommandTypes.CopilotRelated]: (request: protocol.CopilotRelatedRequest) => {
return this.requiredResponse(this.getCopilotRelatedInfo(request.arguments));
},
}));
public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse): void {
+16
View File
@@ -2,6 +2,7 @@ import {
__String,
ApplicableRefactorInfo,
ApplyCodeActionCommandResult,
arrayFrom,
AssignmentDeclarationKind,
BaseType,
BinaryExpression,
@@ -233,6 +234,7 @@ import {
Node,
NodeArray,
NodeFlags,
nodeIsSynthesized,
noop,
normalizePath,
normalizeSpans,
@@ -1602,6 +1604,7 @@ const invalidOperationsInPartialSemanticMode: readonly (keyof LanguageService)[]
"provideInlayHints",
"getSupportedCodeFixes",
"getPasteEdits",
"getImports",
];
const invalidOperationsInSyntacticMode: readonly (keyof LanguageService)[] = [
@@ -3364,6 +3367,18 @@ export function createLanguageService(
);
}
function getImports(fileName: string): readonly string[] {
synchronizeHostData();
const file = getValidSourceFile(fileName);
let imports: Set<string> | undefined;
for (const specifier of file.imports) {
if (nodeIsSynthesized(specifier)) continue;
const name = program.getResolvedModuleFromModuleSpecifier(specifier, file)?.resolvedModule?.resolvedFileName;
if (name) (imports ??= new Set()).add(name);
}
return imports ? arrayFrom(imports) : emptyArray;
}
const ls: LanguageService = {
dispose,
cleanupSemanticCache,
@@ -3438,6 +3453,7 @@ export function createLanguageService(
preparePasteEditsForFile,
getPasteEdits,
mapCode,
getImports,
};
switch (languageServiceMode) {
+1
View File
@@ -697,6 +697,7 @@ export interface LanguageService {
getSupportedCodeFixes(fileName?: string): readonly string[];
/** @internal */ mapCode(fileName: string, contents: string[], focusLocations: TextSpan[][] | undefined, formatOptions: FormatCodeSettings, preferences: UserPreferences): readonly FileTextChanges[];
/** @internal */ getImports(fileName: string): readonly string[];
dispose(): void;
preparePasteEditsForFile(fileName: string, copiedTextRanges: TextRange[]): boolean;