Skip to content

Commit

Permalink
#cpp chat variable
Browse files Browse the repository at this point in the history
  • Loading branch information
lukka committed Mar 5, 2024
1 parent cdc9dd8 commit 57a3f1b
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
"Snippets"
],
"enabledApiProposals": [
"terminalDataWriteEvent"
"terminalDataWriteEvent",
"chatParticipant",
"chatVariableResolver"
],
"capabilities": {
"untrustedWorkspaces": {
Expand Down
16 changes: 16 additions & 0 deletions Extension/src/LanguageServer/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,14 @@ interface DidChangeActiveEditorParams {
selection?: Range;
}

export interface ChatContextResult {
language: string;
standardVersion: string;
compiler: string;
targetPlatform: string;
targetArchitecture: string;
}

// Requests
const InitializationRequest: RequestType<CppInitializationParams, string, void> = new RequestType<CppInitializationParams, string, void>('cpptools/initialize');
const QueryCompilerDefaultsRequest: RequestType<QueryDefaultCompilerParams, configs.CompilerDefaults, void> = new RequestType<QueryDefaultCompilerParams, configs.CompilerDefaults, void>('cpptools/queryCompilerDefaults');
Expand All @@ -553,6 +561,7 @@ const ExtractToFunctionRequest: RequestType<ExtractToFunctionParams, WorkspaceEd
const GoToDirectiveInGroupRequest: RequestType<GoToDirectiveInGroupParams, Position | undefined, void> = new RequestType<GoToDirectiveInGroupParams, Position | undefined, void>('cpptools/goToDirectiveInGroup');
const GenerateDoxygenCommentRequest: RequestType<GenerateDoxygenCommentParams, GenerateDoxygenCommentResult | undefined, void> = new RequestType<GenerateDoxygenCommentParams, GenerateDoxygenCommentResult, void>('cpptools/generateDoxygenComment');
const ChangeCppPropertiesRequest: RequestType<CppPropertiesParams, void, void> = new RequestType<CppPropertiesParams, void, void>('cpptools/didChangeCppProperties');
const CppContextRequest: RequestType<void, ChatContextResult, void> = new RequestType<void, ChatContextResult, void>('cpptools/getChatContext');

// Notifications to the server
const DidOpenNotification: NotificationType<DidOpenTextDocumentParams> = new NotificationType<DidOpenTextDocumentParams>('textDocument/didOpen');
Expand Down Expand Up @@ -778,6 +787,7 @@ export interface Client {
getShowConfigureIntelliSenseButton(): boolean;
setShowConfigureIntelliSenseButton(show: boolean): void;
addTrustedCompiler(path: string): Promise<void>;
getChatContext(): Promise<ChatContextResult | undefined>;
}

export function createClient(workspaceFolder?: vscode.WorkspaceFolder): Client {
Expand Down Expand Up @@ -2187,6 +2197,11 @@ export class DefaultClient implements Client {
await this.languageClient.sendNotification(DidOpenNotification, params);
}

public async getChatContext(): Promise<ChatContextResult | undefined> {
await this.ready;
return this.languageClient.sendRequest(CppContextRequest, null);
}

/**
* a Promise that can be awaited to know when it's ok to proceed.
*
Expand Down Expand Up @@ -4007,4 +4022,5 @@ class NullClient implements Client {
getShowConfigureIntelliSenseButton(): boolean { return false; }
setShowConfigureIntelliSenseButton(show: boolean): void { }
addTrustedCompiler(path: string): Promise<void> { return Promise.resolve(); }
getChatContext(): Promise<ChatContextResult> { return Promise.resolve({} as ChatContextResult); }
}
78 changes: 77 additions & 1 deletion Extension/src/LanguageServer/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { logAndReturn } from '../Utility/Async/returns';
import * as util from '../common';
import { PlatformInformation } from '../platform';
import * as telemetry from '../telemetry';
import { Client, DefaultClient, DoxygenCodeActionCommandArguments, openFileVersions } from './client';
import { ChatContextResult, Client, DefaultClient, DoxygenCodeActionCommandArguments, openFileVersions } from './client';
import { ClientCollection } from './clientCollection';
import { CodeActionDiagnosticInfo, CodeAnalysisDiagnosticIdentifiersAndUri, codeAnalysisAllFixes, codeAnalysisCodeToFixes, codeAnalysisFileToCodeActions } from './codeAnalysis';
import { CppBuildTaskProvider } from './cppBuildTaskProvider';
Expand Down Expand Up @@ -246,6 +246,78 @@ export async function activate(): Promise<void> {
clients.timeTelemetryCollector.setFirstFile(activeEditor.document.uri);
activeDocument = activeEditor.document;
}

await setupCppChatVariable(util.extensionContext);
}

export async function setupCppChatVariable(context: vscode.ExtensionContext | undefined): Promise<void>
{
if (!context) {
return;
}

vscode.chat.registerChatVariableResolver('cpp',
`Describes the the C++ language features that can be used according
to the following information: the C++ language standard version, the target architecture and target operating system.`, {
resolve: async (name, _context, _token) => {
function fixUpLanguage(languageId: string) {
const languageIdToLanguage: { [id: string]: string } =
{ 'c': 'C', 'cpp': 'C++', 'cuda-cpp': 'CUDA C++' };
return languageIdToLanguage[languageId] || languageId;
}

function fixUpCompiler(compilerId: string) {
const compilerIdToCompiler: { [id: string]: string } =
{ 'msvc': 'MSVC', 'clang': 'Clang', 'gcc': 'GCC' };
return compilerIdToCompiler[compilerId] || compilerId;
}

function fixUpStandardVersion(stdVerId: string) {
const stdVerIdToStdVer: { [id: string]: string } =
{ 'c++98': 'C++98', 'c++03': 'C++03', 'c++11': 'C++11', 'c++14': 'C++14', 'c++17': 'C++17',
'c++20': 'C++20', 'c++23': 'C++23', 'c90' : "C90", 'c99': "C99", 'c11': "C11", 'c17': "C17",

Check warning on line 278 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24

Check warning on line 278 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24

Check warning on line 278 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24
'c23': "C23" };

Check warning on line 279 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24

Check warning on line 279 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24

Check warning on line 279 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24
return stdVerIdToStdVer[stdVerId] || stdVerId;
}

function fixTargetPlatform(targetPlatformId: string) {
const platformIdToPlatform: { [id: string]: string } = { 'windows': 'Windows', 'Linux': 'Linux', 'macos': 'macOS' };
return platformIdToPlatform[targetPlatformId] || targetPlatformId;
}

if (name !== 'cpp') {
return undefined;
}

// Return undefined if the active document is not a C++/C/CUDA/Header file.
const currentDoc = vscode.window.activeTextEditor?.document;
if (!currentDoc || (!util.isCpp(currentDoc) && !util.isHeaderFile(currentDoc.uri))) {
return undefined;
}

const chatContext: ChatContextResult | undefined = await getChatContext();
if (!chatContext) {
return undefined;
}

telemetry.logCppChatVariableEvent('cpp',
{ "language": chatContext.language, "compiler": chatContext.compiler, "standardVersion": chatContext.standardVersion,
"targetPlatform": chatContext.targetPlatform, "targetArchitecture": chatContext.targetArchitecture });

Check warning on line 305 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24

Check warning on line 305 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24

Check warning on line 305 in Extension/src/LanguageServer/extension.ts

View workflow job for this annotation

GitHub Actions / job / build

Expected indentation of 22 spaces but found 24

const language = fixUpLanguage(chatContext.language);
const compiler = fixUpCompiler(chatContext.compiler);
const standardVersion = fixUpStandardVersion(chatContext.standardVersion);
const targetPlatform = fixTargetPlatform(chatContext.targetPlatform);
const value = `I am working on a project of the following nature:
- Using ${language}. Prefer a solution written in ${language} to any other language. Call out which language you are using in the answer.
- Using the ${language} standard language version ${standardVersion}. Prefer solutions using the new and more recent features introduced in ${standardVersion}. Call out which standard version you are using in the answer.
- Using the ${compiler} compiler. Prefer solutions supported by the ${compiler} compiler.
- Targeting the ${targetPlatform} platform. Prefer solutions and API that are supported on ${targetPlatform}.
- Targeting the ${chatContext.targetArchitecture} architecture. Prefer solutions and techniques that are supported on the ${chatContext.targetArchitecture} architecture.
`;
return [ { level: vscode.ChatVariableLevel.Full, value: value } ];
}
});
}

export function updateLanguageConfigurations(): void {
Expand Down Expand Up @@ -1305,3 +1377,7 @@ export async function preReleaseCheck(): Promise<void> {
}
}
}

export async function getChatContext(): Promise<ChatContextResult | undefined> {
return clients?.ActiveClient?.getChatContext() ?? undefined;
}
14 changes: 14 additions & 0 deletions Extension/src/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,20 @@ export function logLanguageServerEvent(eventName: string, properties?: Record<st
sendTelemetry();
}

export function logCppChatVariableEvent(eventName: string, properties?: Record<string, string>, metrics?: Record<string, number>): void {
const sendTelemetry = () => {
if (experimentationTelemetry) {
const eventNamePrefix: string = "C_Cpp/Copilot/Chat/Variable/";
experimentationTelemetry.sendTelemetryEvent(eventNamePrefix + eventName, properties, metrics);
}
};

if (is.promise(initializationPromise)) {
return void initializationPromise.catch(logAndReturn.undefined).then(sendTelemetry).catch(logAndReturn.undefined);
}
sendTelemetry();
}

function getPackageInfo(): IPackageInfo {
return {
name: util.packageJson.publisher + "." + util.packageJson.name,
Expand Down

0 comments on commit 57a3f1b

Please sign in to comment.