import * as vscode from 'vscode' ; import * as os from 'os' ; import { AttachPicker , RemoteAttachPicker , AttachItemsProvider } from './attachToProcess' ; import { NativeAttachItemsProviderFactory } from './nativeAttach' ; import { QuickPickConfigurationProvider , ConfigurationAssetProviderFactory , CppVsDbgConfigurationProvider , CppDbgConfigurationProvider , ConfigurationSnippetProvider , IConfigurationAssetProvider } from './configurationProvider' ; import { CppdbgDebugAdapterDescriptorFactory , CppvsdbgDebugAdapterDescriptorFactory } from './debugAdapterDescriptorFactory' ; import * as util from '../common' ; import * as Telemetry from '../telemetry' ; import * as nls from 'vscode-nls' ; import { cppBuildTaskProvider } from '../LanguageServer/extension' ; nls . config ( { messageFormat : nls . MessageFormat . bundle , bundleFormat : nls . BundleFormat . standalone } ) ( ) ; const localize = nls . loadMessageBundle ( ) ; const disposables = [ ] ; export function buildAndDebugActiveFileStr ( ) { return ` - ${ localize ( "build.and.debug.active.file" , 'Build and debug active file' ) }` ; } export function initialize ( context ) { const attachItemsProvider = NativeAttachItemsProviderFactory . Get ( ) ; const attacher = new AttachPicker ( attachItemsProvider ) ; disposables . push ( vscode . commands . registerCommand ( 'extension.pickNativeProcess' , ( ) => attacher . ShowAttachEntries ( ) ) ) ; const remoteAttacher = new RemoteAttachPicker ( ) ; disposables . push ( vscode . commands . registerCommand ( 'extension.pickRemoteNativeProcess' , ( any ) => remoteAttacher . ShowAttachEntries ( any ) ) ) ; const configurationProvider = ConfigurationAssetProviderFactory . getConfigurationProvider ( ) ; let vsdbgProvider = null ; if ( os . platform ( ) === 'win32' ) { vsdbgProvider = new CppVsDbgConfigurationProvider ( configurationProvider ) ; disposables . push ( vscode . debug . registerDebugConfigurationProvider ( 'cppvsdbg' , new QuickPickConfigurationProvider ( vsdbgProvider ) ) ) ; } const provider = new CppDbgConfigurationProvider ( configurationProvider ) ; disposables . push ( vscode . debug . registerDebugConfigurationProvider ( 'cppdbg' , new QuickPickConfigurationProvider ( provider ) ) ) ; disposables . push ( vscode . commands . registerTextEditorCommand ( "C_Cpp.BuildAndDebugActiveFile" , async ( textEditor , edit , ... args ) => { const folder = vscode . workspace . getWorkspaceFolder ( textEditor . document . uri ) ; if ( ! folder ) { vscode . window . showErrorMessage ( localize ( "single_file_mode_not_available" , "This command is not available for single-file mode." ) ) ; return Promise . resolve ( ) ; } if ( ! util . fileIsCOrCppSource ( textEditor . document . uri . fsPath ) ) { vscode . window . showErrorMessage ( localize ( "cannot.build.non.cpp" , 'Cannot build and debug because the active file is not a C or C++ source file.' ) ) ; return Promise . resolve ( ) ; } const configs = ( await provider . provideDebugConfigurations ( folder ) ) . filter ( config => config . name . indexOf ( buildAndDebugActiveFileStr ( ) ) !== - 1 ) ; if ( vsdbgProvider ) { const vsdbgConfigs = ( await vsdbgProvider . provideDebugConfigurations ( folder ) ) . filter ( config => config . name . indexOf ( buildAndDebugActiveFileStr ( ) ) !== - 1 ) ; if ( vsdbgConfigs ) { configs . push ( ... vsdbgConfigs ) ; } } interface MenuItem extends vscode . QuickPickItem { configuration : vscode . DebugConfiguration ; } const items = configs . map < MenuItem > ( config => ( { label : config . name , configuration : config , description : config . detail } ) ) ; const selection = await vscode . window . showQuickPick ( items , { placeHolder : ( items . length === 0 ? localize ( "no.compiler.found" , "No compiler found" ) : localize ( "select.configuration" , "Select a configuration" ) ) } ) ; if ( ! selection ) { return ; } if ( selection . label . startsWith ( "cl.exe" ) ) { if ( ! process . env . DevEnvDir || process . env . DevEnvDir . length === 0 ) { vscode . window . showErrorMessage ( localize ( "cl.exe.not.available" , '{0} build and debug is only usable when VS Code is run from the Developer Command Prompt for VS.' , "cl.exe" ) ) ; return ; } } if ( selection . configuration . preLaunchTask ) { if ( folder ) { try { await cppBuildTaskProvider . ensureBuildTaskExists ( selection . configuration . preLaunchTask ) ; Telemetry . logDebuggerEvent ( "buildAndDebug" , { "success" : "false" } ) ; } catch ( errJS ) { const e = errJS as Error ; if ( e && e . message === util . failedToParseJson ) { vscode . window . showErrorMessage ( util . failedToParseJson ) ; } return ; } } else { return ; } } try { await cppBuildTaskProvider . ensureDebugConfigExists ( selection . configuration . name ) ; try { await vscode . debug . startDebugging ( folder , selection . configuration . name ) ; Telemetry . logDebuggerEvent ( "buildAndDebug" , { "success" : "true" } ) ; } catch ( e ) { Telemetry . logDebuggerEvent ( "buildAndDebug" , { "success" : "false" } ) ; } } catch ( e ) { try { await vscode . debug . startDebugging ( folder , selection . configuration ) ; Telemetry . logDebuggerEvent ( "buildAndDebug" , { "success" : "true" } ) ; } catch ( e ) { Telemetry . logDebuggerEvent ( "buildAndDebug" , { "success" : "false" } ) ; } } } ) ) ; configurationProvider . getConfigurationSnippets ( ) ; const launchJsonDocumentSelector = [ { scheme : 'file' , language : 'jsonc' , pattern : '**/launch.json' } ] ; disposables . push ( vscode . languages . registerCompletionItemProvider ( launchJsonDocumentSelector , new ConfigurationSnippetProvider ( configurationProvider ) ) ) ; disposables . push ( vscode . debug . registerDebugAdapterDescriptorFactory ( CppvsdbgDebugAdapterDescriptorFactory . DEBUG_TYPE , new CppvsdbgDebugAdapterDescriptorFactory ( context ) ) ) ; disposables . push ( vscode . debug . registerDebugAdapterDescriptorFactory ( CppdbgDebugAdapterDescriptorFactory . DEBUG_TYPE , new CppdbgDebugAdapterDescriptorFactory ( context ) ) ) ; vscode . Disposable . from ( ... disposables ) ; } export function dispose ( ) { disposables . forEach ( d => d . dispose ( ) ) ; }