@@ -53,7 +53,7 @@ import {
5353import { Location , TextEdit , WorkspaceEdit } from './commonTypes' ;
5454import * as configs from './configurations' ;
5555import { DataBinding } from './dataBinding' ;
56- import { CppSourceStr , clients , configPrefix , updateLanguageConfigurations , watchForCrashes } from './extension' ;
56+ import { CppSourceStr , clients , configPrefix , updateLanguageConfigurations , usesCrashHandler , watchForCrashes } from './extension' ;
5757import { LocalizeStringParams , getLocaleId , getLocalizedString } from './localization' ;
5858import { PersistentFolderState , PersistentWorkspaceState } from './persistentState' ;
5959import { createProtocolFilter } from './protocolFilter' ;
@@ -111,10 +111,6 @@ export function disposeWorkspaceData(): void {
111111 workspaceDisposables = [ ] ;
112112}
113113
114- function logTelemetry ( notificationBody : TelemetryPayload ) : void {
115- telemetry . logLanguageServerEvent ( notificationBody . event , notificationBody . properties , notificationBody . metrics ) ;
116- }
117-
118114/** Note: We should not await on the following functions,
119115 * or any function that returns a promise acquired from them,
120116 * vscode.window.showInformationMessage, vscode.window.showWarningMessage, vscode.window.showErrorMessage
@@ -548,7 +544,8 @@ interface GetIncludesResult
548544}
549545
550546// Requests
551- const InitializationRequest : RequestType < CppInitializationParams , string , void > = new RequestType < CppInitializationParams , string , void > ( 'cpptools/initialize' ) ;
547+ const PreInitializationRequest : RequestType < void , string , void > = new RequestType < void , string , void > ( 'cpptools/preinitialize' ) ;
548+ const InitializationRequest : RequestType < CppInitializationParams , void , void > = new RequestType < CppInitializationParams , void , void > ( 'cpptools/initialize' ) ;
552549const QueryCompilerDefaultsRequest : RequestType < QueryDefaultCompilerParams , configs . CompilerDefaults , void > = new RequestType < QueryDefaultCompilerParams , configs . CompilerDefaults , void > ( 'cpptools/queryCompilerDefaults' ) ;
553550const QueryTranslationUnitSourceRequest : RequestType < QueryTranslationUnitSourceParams , QueryTranslationUnitSourceResult , void > = new RequestType < QueryTranslationUnitSourceParams , QueryTranslationUnitSourceResult , void > ( 'cpptools/queryTranslationUnitSource' ) ;
554551const SwitchHeaderSourceRequest : RequestType < SwitchHeaderSourceParams , string , void > = new RequestType < SwitchHeaderSourceParams , string , void > ( 'cpptools/didSwitchHeaderSource' ) ;
@@ -1596,10 +1593,14 @@ export class DefaultClient implements Client {
15961593 languageClient . registerProposedFeatures ( ) ;
15971594 await languageClient . start ( ) ;
15981595
1596+ if ( usesCrashHandler ( ) ) {
1597+ watchForCrashes ( await languageClient . sendRequest ( PreInitializationRequest , null ) ) ;
1598+ }
1599+
15991600 // Move initialization to a separate message, so we can see log output from it.
16001601 // A request is used in order to wait for completion and ensure that no subsequent
16011602 // higher priority message may be processed before the Initialization request.
1602- watchForCrashes ( await languageClient . sendRequest ( InitializationRequest , cppInitializationParams ) ) ;
1603+ await languageClient . sendRequest ( InitializationRequest , cppInitializationParams ) ;
16031604 }
16041605
16051606 public async sendDidChangeSettings ( ) : Promise < void > {
@@ -2000,13 +2001,17 @@ export class DefaultClient implements Client {
20002001 onFinished ( ) ;
20012002 return ;
20022003 }
2003- telemetry . logLanguageServerEvent ( 'provideCustomConfiguration' , { providerId } ) ;
2004- void this . provideCustomConfigurationAsync ( docUri , requestFile , replaceExisting , onFinished , provider ) ;
2004+ try {
2005+ DefaultClient . isStarted . reset ( ) ;
2006+ const status = await this . provideCustomConfigurationAsync ( docUri , requestFile , replaceExisting , provider ) ;
2007+ telemetry . logLanguageServerEvent ( 'provideCustomConfiguration' , { providerId, status } ) ;
2008+ } finally {
2009+ onFinished ( ) ;
2010+ DefaultClient . isStarted . resolve ( ) ;
2011+ }
20052012 }
20062013
2007- private async provideCustomConfigurationAsync ( docUri : vscode . Uri , requestFile : string | undefined , replaceExisting : boolean | undefined , onFinished : ( ) => void , provider : CustomConfigurationProvider1 ) {
2008- DefaultClient . isStarted . reset ( ) ;
2009-
2014+ private async provideCustomConfigurationAsync ( docUri : vscode . Uri , requestFile : string | undefined , replaceExisting : boolean | undefined , provider : CustomConfigurationProvider1 ) : Promise < string > {
20102015 const tokenSource : vscode . CancellationTokenSource = new vscode . CancellationTokenSource ( ) ;
20112016
20122017 const params : QueryTranslationUnitSourceParams = {
@@ -2018,14 +2023,12 @@ export class DefaultClient implements Client {
20182023 const response : QueryTranslationUnitSourceResult = await this . languageClient . sendRequest ( QueryTranslationUnitSourceRequest , params ) ;
20192024 if ( ! response . candidates || response . candidates . length === 0 ) {
20202025 // If we didn't receive any candidates, no configuration is needed.
2021- onFinished ( ) ;
2022- DefaultClient . isStarted . resolve ( ) ;
2023- return ;
2026+ return "noCandidates" ;
20242027 }
20252028
20262029 // Need to loop through candidates, to see if we can get a custom configuration from any of them.
20272030 // Wrap all lookups in a single task, so we can apply a timeout to the entire duration.
2028- const provideConfigurationAsync : ( ) => Thenable < SourceFileConfigurationItem [ ] | null | undefined > = async ( ) => {
2031+ const provideConfigurationAsync : ( ) => Thenable < SourceFileConfigurationItem [ ] | undefined > = async ( ) => {
20292032 const uris : vscode . Uri [ ] = [ ] ;
20302033 for ( let i : number = 0 ; i < response . candidates . length ; ++ i ) {
20312034 const candidate : string = response . candidates [ i ] ;
@@ -2085,44 +2088,41 @@ export class DefaultClient implements Client {
20852088 }
20862089 return configs as SourceFileConfigurationItem [ ] ;
20872090 }
2088- if ( tokenSource . token . isCancellationRequested ) {
2089- return null ;
2090- }
2091+ return undefined ;
20912092 } ;
2093+ let result : string = "success" ;
20922094 try {
2093- const configs : SourceFileConfigurationItem [ ] | null | undefined = await this . callTaskWithTimeout ( provideConfigurationAsync , configProviderTimeout , tokenSource ) ;
2095+ const configs : SourceFileConfigurationItem [ ] | undefined = await this . callTaskWithTimeout ( provideConfigurationAsync , configProviderTimeout , tokenSource ) ;
20942096 if ( configs && configs . length > 0 ) {
20952097 this . sendCustomConfigurations ( configs , provider . version ) ;
2098+ } else {
2099+ result = "noConfigurations" ;
20962100 }
2097- onFinished ( ) ;
20982101 } catch ( err ) {
2099- if ( requestFile ) {
2100- onFinished ( ) ;
2101- return ;
2102- }
2103- const settings : CppSettings = new CppSettings ( this . RootUri ) ;
2104- if ( settings . configurationWarnings && ! this . isExternalHeader ( docUri ) && ! vscode . debug . activeDebugSession ) {
2105- const dismiss : string = localize ( "dismiss.button" , "Dismiss" ) ;
2106- const disable : string = localize ( "disable.warnings.button" , "Disable Warnings" ) ;
2107- const configName : string | undefined = this . configuration . CurrentConfiguration ?. name ;
2108- if ( ! configName ) {
2109- return ;
2110- }
2111- let message : string = localize ( "unable.to.provide.configuration" ,
2112- "{0} is unable to provide IntelliSense configuration information for '{1}'. Settings from the '{2}' configuration will be used instead." ,
2113- provider . name , docUri . fsPath , configName ) ;
2114- if ( err ) {
2115- message += ` (${ err } )` ;
2116- }
2102+ result = "timeout" ;
2103+ if ( ! requestFile ) {
2104+ const settings : CppSettings = new CppSettings ( this . RootUri ) ;
2105+ if ( settings . configurationWarnings && ! this . isExternalHeader ( docUri ) && ! vscode . debug . activeDebugSession ) {
2106+ const dismiss : string = localize ( "dismiss.button" , "Dismiss" ) ;
2107+ const disable : string = localize ( "disable.warnings.button" , "Disable Warnings" ) ;
2108+ const configName : string | undefined = this . configuration . CurrentConfiguration ?. name ;
2109+ if ( ! configName ) {
2110+ return "noConfigName" ;
2111+ }
2112+ let message : string = localize ( "unable.to.provide.configuration" ,
2113+ "{0} is unable to provide IntelliSense configuration information for '{1}'. Settings from the '{2}' configuration will be used instead." ,
2114+ provider . name , docUri . fsPath , configName ) ;
2115+ if ( err ) {
2116+ message += ` (${ err } )` ;
2117+ }
21172118
2118- if ( await vscode . window . showInformationMessage ( message , dismiss , disable ) === disable ) {
2119- settings . toggleSetting ( "configurationWarnings" , "enabled" , "disabled" ) ;
2119+ if ( await vscode . window . showInformationMessage ( message , dismiss , disable ) === disable ) {
2120+ settings . toggleSetting ( "configurationWarnings" , "enabled" , "disabled" ) ;
2121+ }
21202122 }
21212123 }
2122- } finally {
2123- DefaultClient . isStarted . resolve ( ) ;
21242124 }
2125-
2125+ return result ;
21262126 }
21272127
21282128 private async handleRequestCustomConfig ( requestFile : string ) : Promise < void > {
@@ -2323,7 +2323,7 @@ export class DefaultClient implements Client {
23232323
23242324 this . languageClient . onNotification ( ReloadWindowNotification , ( ) => void util . promptForReloadWindowDueToSettingsChange ( ) ) ;
23252325 this . languageClient . onNotification ( UpdateTrustedCompilersNotification , ( e ) => void this . addTrustedCompiler ( e . compilerPath ) ) ;
2326- this . languageClient . onNotification ( LogTelemetryNotification , logTelemetry ) ;
2326+ this . languageClient . onNotification ( LogTelemetryNotification , ( e ) => this . logTelemetry ( e ) ) ;
23272327 this . languageClient . onNotification ( ReportStatusNotification , ( e ) => void this . updateStatus ( e ) ) ;
23282328 this . languageClient . onNotification ( ReportTagParseStatusNotification , ( e ) => this . updateTagParseStatus ( e ) ) ;
23292329 this . languageClient . onNotification ( CompileCommandsPathsNotification , ( e ) => void this . promptCompileCommands ( e ) ) ;
@@ -2562,6 +2562,13 @@ export class DefaultClient implements Client {
25622562 }
25632563 }
25642564
2565+ private logTelemetry ( notificationBody : TelemetryPayload ) : void {
2566+ if ( notificationBody . event === "includeSquiggles" && this . configurationProvider && notificationBody . properties ) {
2567+ notificationBody . properties [ "providerId" ] = this . configurationProvider ;
2568+ }
2569+ telemetry . logLanguageServerEvent ( notificationBody . event , notificationBody . properties , notificationBody . metrics ) ;
2570+ }
2571+
25652572 private async updateStatus ( notificationBody : ReportStatusNotificationBody ) : Promise < void > {
25662573 const message : string = notificationBody . status ;
25672574 util . setProgress ( util . getProgressExecutableSuccess ( ) ) ;
0 commit comments