diff --git a/package.json b/package.json index d215f60ffe45..ea7646bc0dcf 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "theme": "dark" }, "engines": { - "vscode": "^1.48.0" + "vscode": "^1.49.0" }, "keywords": [ "python", @@ -1670,7 +1670,7 @@ { "command": "python.datascience.showDataViewer", "group": "1_view", - "when": "debugProtocolVariableMenuContext == 'viewableInDataViewer'" + "when": "python.isDebuggerDataViewerExperimentEnabled && debugProtocolVariableMenuContext == 'viewableInDataViewer'" } ] }, @@ -2127,6 +2127,7 @@ "RunByLine - experiment", "tryPylance", "jediLSP", + "debuggerDataViewer", "All" ] }, @@ -2152,6 +2153,7 @@ "RunByLine - experiment", "tryPylance", "jediLSP", + "debuggerDataViewer", "All" ] }, diff --git a/src/client/common/serviceRegistry.ts b/src/client/common/serviceRegistry.ts index 444b666c70e3..0d61342e47ab 100644 --- a/src/client/common/serviceRegistry.ts +++ b/src/client/common/serviceRegistry.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import { IExtensionSingleActivationService } from '../activation/types'; import { IExperimentService, IFileDownloader, IHttpClient, IInterpreterPathService } from '../common/types'; +import { DebuggerDataViewerExperimentEnabler } from '../datascience/data-viewing/debuggerDataViewerExperimentEnabler'; import { LiveShareApi } from '../datascience/liveshare/liveshare'; import { INotebookExecutionLogger } from '../datascience/types'; import { IServiceManager } from '../ioc/types'; @@ -218,5 +219,9 @@ export function registerTypes(serviceManager: IServiceManager) { IExtensionSingleActivationService, DebugSessionTelemetry ); + serviceManager.addSingleton( + IExtensionSingleActivationService, + DebuggerDataViewerExperimentEnabler + ); serviceManager.addSingleton(ICustomEditorService, CustomEditorService); } diff --git a/src/client/datascience/commands/commandRegistry.ts b/src/client/datascience/commands/commandRegistry.ts index d1778fe59995..f21dda8a2e03 100644 --- a/src/client/datascience/commands/commandRegistry.ts +++ b/src/client/datascience/commands/commandRegistry.ts @@ -16,6 +16,7 @@ import { IConfigurationService, IDisposable, IOutputChannel } from '../../common import { DataScience } from '../../common/utils/localize'; import { noop } from '../../common/utils/misc'; import { captureTelemetry, sendTelemetryEvent } from '../../telemetry'; +import { EventName } from '../../telemetry/constants'; import { Commands, JUPYTER_OUTPUT_CHANNEL, Telemetry } from '../constants'; import { IDataViewerFactory } from '../data-viewing/types'; import { DataViewerChecker } from '../interactive-common/dataViewerChecker'; @@ -481,7 +482,7 @@ export class CommandRegistry implements IDisposable { } private async onVariablePanelShowDataViewerRequest(request: IShowDataViewerFromVariablePanel) { - sendTelemetryEvent(Telemetry.OpenDataViewerFromVariableWindowRequest); + sendTelemetryEvent(EventName.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_REQUEST); if (this.debugService.activeDebugSession) { const jupyterVariable = convertDebugProtocolVariableToIJupyterVariable( request.variable as DebugProtocol.Variable @@ -495,10 +496,10 @@ export class CommandRegistry implements IDisposable { if (columnSize && (await this.dataViewerChecker.isRequestedColumnSizeAllowed(columnSize))) { const title: string = `${DataScience.dataExplorerTitle()} - ${jupyterVariable.name}`; await this.dataViewerFactory.create(jupyterVariableDataProvider, title); - sendTelemetryEvent(Telemetry.OpenDataViewerFromVariableWindowSuccess); + sendTelemetryEvent(EventName.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_SUCCESS); } } catch (e) { - sendTelemetryEvent(Telemetry.OpenDataViewerFromVariableWindowError); + sendTelemetryEvent(EventName.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_ERROR, undefined, e); traceError(e); this.appShell.showErrorMessage(e.toString()); } diff --git a/src/client/datascience/constants.ts b/src/client/datascience/constants.ts index 894d26bcfb9e..d9fbf31a15ee 100644 --- a/src/client/datascience/constants.ts +++ b/src/client/datascience/constants.ts @@ -410,10 +410,7 @@ export enum Telemetry { TrustAllNotebooks = 'DATASCIENCE.TRUST_ALL_NOTEBOOKS', TrustNotebook = 'DATASCIENCE.TRUST_NOTEBOOK', DoNotTrustNotebook = 'DATASCIENCE.DO_NOT_TRUST_NOTEBOOK', - NotebookTrustPromptShown = 'DATASCIENCE.NOTEBOOK_TRUST_PROMPT_SHOWN', - OpenDataViewerFromVariableWindowRequest = 'DATASCIENCE.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_REQUEST', - OpenDataViewerFromVariableWindowError = 'DATASCIENCE.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_ERROR', - OpenDataViewerFromVariableWindowSuccess = 'DATASCIENCE.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_SUCCESS' + NotebookTrustPromptShown = 'DATASCIENCE.NOTEBOOK_TRUST_PROMPT_SHOWN' } export enum NativeKeyboardCommandTelemetry { diff --git a/src/client/datascience/data-viewing/debuggerDataViewerExperimentEnabler.ts b/src/client/datascience/data-viewing/debuggerDataViewerExperimentEnabler.ts new file mode 100644 index 000000000000..a6d0b2b76298 --- /dev/null +++ b/src/client/datascience/data-viewing/debuggerDataViewerExperimentEnabler.ts @@ -0,0 +1,26 @@ +import { inject, injectable } from 'inversify'; +import { IExtensionSingleActivationService } from '../../activation/types'; +import { ICommandManager } from '../../common/application/types'; +import { ContextKey } from '../../common/contextKey'; +import { traceError } from '../../common/logger'; +import { IExperimentService } from '../../common/types'; + +@injectable() +export class DebuggerDataViewerExperimentEnabler implements IExtensionSingleActivationService { + constructor( + @inject(ICommandManager) private readonly commandManager: ICommandManager, + @inject(IExperimentService) private readonly experimentService: IExperimentService + ) {} + public async activate() { + this.activateInternal().catch(traceError.bind('Failed to activate debuggerDataViewerExperimentEnabler')); + } + private async activateInternal() { + // This context key controls the visibility of the 'View Variable in Data Viewer' + // context menu item from the variable window context menu during a debugging session + const isDataViewerExperimentEnabled = new ContextKey( + 'python.isDebuggerDataViewerExperimentEnabled', + this.commandManager + ); + await isDataViewerExperimentEnabled.set(await this.experimentService.inExperiment('debuggerDataViewer')); + } +} diff --git a/src/client/datascience/interactive-common/interactiveWindowTypes.ts b/src/client/datascience/interactive-common/interactiveWindowTypes.ts index 128dbbc7df37..05c00622a965 100644 --- a/src/client/datascience/interactive-common/interactiveWindowTypes.ts +++ b/src/client/datascience/interactive-common/interactiveWindowTypes.ts @@ -2,7 +2,8 @@ // Licensed under the MIT License. 'use strict'; import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api'; -import { DebugProtocolVariable, DebugProtocolVariableContainer, Uri } from 'vscode'; +import { Uri } from 'vscode'; +import { DebugProtocolVariable, DebugProtocolVariableContainer } from '../../../../types/vscode-proposed'; import { DebugState, IServerState } from '../../../datascience-ui/interactive-common/mainState'; import type { KernelMessage } from '@jupyterlab/services'; diff --git a/src/client/telemetry/constants.ts b/src/client/telemetry/constants.ts index b04516bd48b5..9d9b21f48372 100644 --- a/src/client/telemetry/constants.ts +++ b/src/client/telemetry/constants.ts @@ -55,6 +55,9 @@ export enum EventName { DEBUGGER_ATTACH_TO_LOCAL_PROCESS = 'DEBUGGER.ATTACH_TO_LOCAL_PROCESS', DEBUGGER_CONFIGURATION_PROMPTS = 'DEBUGGER.CONFIGURATION.PROMPTS', DEBUGGER_CONFIGURATION_PROMPTS_IN_LAUNCH_JSON = 'DEBUGGER.CONFIGURATION.PROMPTS.IN.LAUNCH.JSON', + OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_REQUEST = 'OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_REQUEST', + OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_ERROR = 'OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_ERROR', + OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_SUCCESS = 'OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_SUCCESS', UNITTEST_STOP = 'UNITTEST.STOP', UNITTEST_DISABLE = 'UNITTEST.DISABLE', UNITTEST_RUN = 'UNITTEST.RUN', diff --git a/src/client/telemetry/index.ts b/src/client/telemetry/index.ts index d110fbd10e6c..9bdcb7c97d05 100644 --- a/src/client/telemetry/index.ts +++ b/src/client/telemetry/index.ts @@ -587,6 +587,9 @@ export interface IEventNamePropertyMapping { */ manuallyEnteredAValue?: boolean; }; + [EventName.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_REQUEST]: never | undefined; + [EventName.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_ERROR]: never | undefined; + [EventName.OPEN_DATAVIEWER_FROM_VARIABLE_WINDOW_SUCCESS]: never | undefined; /** * Telemetry event sent when providing completion provider in launch.json. It is sent just *after* inserting the completion. */ @@ -1772,9 +1775,6 @@ export interface IEventNamePropertyMapping { [Telemetry.SetJupyterURIToUserSpecified]: never | undefined; [Telemetry.ShiftEnterBannerShown]: never | undefined; [Telemetry.ShowDataViewer]: { rows: number | undefined; columns: number | undefined }; - [Telemetry.OpenDataViewerFromVariableWindowRequest]: never | undefined; - [Telemetry.OpenDataViewerFromVariableWindowError]: never | undefined; - [Telemetry.OpenDataViewerFromVariableWindowSuccess]: never | undefined; [Telemetry.CreateNewInteractive]: never | undefined; [Telemetry.StartJupyter]: never | undefined; [Telemetry.StartJupyterProcess]: never | undefined; diff --git a/types/vscode-proposed/index.d.ts b/types/vscode-proposed/index.d.ts index 8c4fc94024b8..4d18934693fd 100644 --- a/types/vscode-proposed/index.d.ts +++ b/types/vscode-proposed/index.d.ts @@ -730,3 +730,22 @@ export namespace notebook { priority?: number ): NotebookCellStatusBarItem; } + +//#region debug + +/** + * A DebugProtocolVariableContainer is an opaque stand-in type for the intersection of the Scope and Variable types defined in the Debug Adapter Protocol. + * See https://microsoft.github.io/debug-adapter-protocol/specification#Types_Scope and https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable. + */ +export interface DebugProtocolVariableContainer { + // Properties: the intersection of DAP's Scope and Variable types. +} + +/** + * A DebugProtocolVariable is an opaque stand-in type for the Variable type defined in the Debug Adapter Protocol. + * See https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable. + */ +export interface DebugProtocolVariable { + // Properties: see details [here](https://microsoft.github.io/debug-adapter-protocol/specification#Base_Protocol_Variable). +} +//#endregion