'use strict' ; import * as path from 'path' ; import * as vscode from 'vscode' ; import { OnTypeFormattingEditProvider } from './Providers/onTypeFormattingEditProvider' ; import { FoldingRangeProvider } from './Providers/foldingRangeProvider' ; import { SemanticTokensProvider } from './Providers/semanticTokensProvider' ; import { DocumentFormattingEditProvider } from './Providers/documentFormattingEditProvider' ; import { DocumentRangeFormattingEditProvider } from './Providers/documentRangeFormattingEditProvider' ; import { DocumentSymbolProvider } from './Providers/documentSymbolProvider' ; import { WorkspaceSymbolProvider } from './Providers/workspaceSymbolProvider' ; import { RenameProvider } from './Providers/renameProvider' ; import { FindAllReferencesProvider } from './Providers/findAllReferencesProvider' ; import { LanguageClient , LanguageClientOptions , ServerOptions , NotificationType , TextDocumentIdentifier , RequestType , ErrorAction , CloseAction , DidOpenTextDocumentParams , Range , Position , DocumentFilter } from 'vscode-languageclient' ; import { SourceFileConfigurationItem , WorkspaceBrowseConfiguration , SourceFileConfiguration , Version } from 'vscode-cpptools' ; import { Status , IntelliSenseStatus } from 'vscode-cpptools/out/testApi' ; import * as util from '../common' ; import * as configs from './configurations' ; import { CppSettings , getEditorConfigSettings , OtherSettings } from './settings' ; import * as telemetry from '../telemetry' ; import { PersistentState , PersistentFolderState } from './persistentState' ; import { UI , getUI } from './ui' ; import { ClientCollection } from './clientCollection' ; import { createProtocolFilter } from './protocolFilter' ; import { DataBinding } from './dataBinding' ; import minimatch = require ( "minimatch" ) ; import * as logger from '../logger' ; import { updateLanguageConfigurations , registerCommands } from './extension' ; import { SettingsTracker , getTracker } from './settingsTracker' ; import { getTestHook , TestHook } from '../testHook' ; import { getCustomConfigProviders , CustomConfigurationProvider1 , isSameProviderExtensionId } from '../LanguageServer/customProviders' ; import * as fs from 'fs' ; import * as os from 'os' ; import * as refs from './references' ; import * as nls from 'vscode-nls' ; import { lookupString , localizedStringCount } from '../nativeStrings' ; nls . config ( { messageFormat : nls . MessageFormat . bundle , bundleFormat : nls . BundleFormat . standalone } ) ( ) ; const localize = nls . loadMessageBundle ( ) ; type LocalizeStringParams = util . LocalizeStringParams ; let ui ; let timeStamp = 0 ; const configProviderTimeout = 2000 ; let languageClient ; let languageClientCrashedNeedsRestart = false ; const languageClientCrashTimes = [ ] ; let clientCollection ; let pendingTask ; let compilerDefaults ; let diagnosticsChannel ; let outputChannel ; let debugChannel ; let warningChannel ; let diagnosticsCollectionIntelliSense ; let diagnosticsCollectionCodeAnalysis ; let workspaceDisposables = [ ] ; export let workspaceReferences ; export const openFileVersions = new Map < string , number > ( ) ; export const cachedEditorConfigSettings = new Map < string , any > ( ) ; export const cachedEditorConfigLookups = new Map < string , boolean > ( ) ; export function disposeWorkspaceData ( ) { workspaceDisposables . forEach ( ( d ) => d . dispose ( ) ) ; workspaceDisposables = [ ] ; } function logTelemetry ( notificationBody ) { telemetry . logLanguageServerEvent ( notificationBody . event , notificationBody . properties , notificationBody . metrics ) ; } /**
 * listen for logging messages from the language server and print them to the Output window
 */ function setupOutputHandlers ( ) { console . assert ( languageClient !== undefined , "This method must not be called until this.languageClient is set in \"onReady\"" ) ; languageClient . onNotification ( DebugProtocolNotification , ( output ) => { if ( ! debugChannel ) { debugChannel = vscode . window . createOutputChannel ( `${ localize ( "c.cpp.debug.protocol" , "C/C++ Debug Protocol" ) }` ) ; workspaceDisposables . push ( debugChannel ) ; } debugChannel . appendLine ( "" ) ; debugChannel . appendLine ( "************************************************************************************************************************" ) ; debugChannel . append ( `${ output }` ) ; } ) ; languageClient . onNotification ( DebugLogNotification , logLocalized ) ; } function log ( output ) { if ( ! outputChannel ) { outputChannel = logger . getOutputChannel ( ) ; workspaceDisposables . push ( outputChannel ) ; } outputChannel . appendLine ( `${ output }` ) ; } function logLocalized ( params ) { const output = util . getLocalizedString ( params ) ; log ( output ) ; } /** Note: We should not await on the following functions,
 * or any funstion that returns a promise acquired from them,
 * vscode.window.showInformationMessage, vscode.window.showWarningMessage, vscode.window.showErrorMessage
*/ function showMessageWindow ( params ) { const message = util . getLocalizedString ( params . localizeStringParams ) ; switch ( params . type ) { case 1 : vscode . window . showErrorMessage ( message ) ; break ; case 2 : vscode . window . showWarningMessage ( message ) ; break ; case 3 : vscode . window . showInformationMessage ( message ) ; break ; default : console . assert ( "Unrecognized type for showMessageWindow" ) ; break ; } } function showWarning ( params ) { const message = util . getLocalizedString ( params . localizeStringParams ) ; let showChannel = false ; if ( ! warningChannel ) { warningChannel = vscode . window . createOutputChannel ( `${ localize ( "c.cpp.warnings" , "C/C++ Configuration Warnings" ) }` ) ; workspaceDisposables . push ( warningChannel ) ; showChannel = true ; } warningChannel . appendLine ( `[${ new Date ( ) . toLocaleString ( ) }] ${ message }` ) ; if ( showChannel ) { warningChannel . show ( true ) ; } } function publishDiagnostics ( params ) { if ( ! diagnosticsCollectionIntelliSense ) { diagnosticsCollectionIntelliSense = vscode . languages . createDiagnosticCollection ( "C/C++" ) ; } const diagnosticsIntelliSense = [ ] ; params . diagnostics . forEach ( ( d ) => { const message = util . getLocalizedString ( d . localizeStringParams ) ; const r = new vscode . Range ( d . range . start . line , d . range . start . character , d . range . end . line , d . range . end . character ) ; const diagnostic = new vscode . Diagnostic ( r , message , d . severity ) ; diagnostic . code = d . code ; diagnostic . source = "C/C++" ; if ( d . relatedInformation ) { diagnostic . relatedInformation = [ ] ; for ( const info of d . relatedInformation ) { const infoRange = new vscode . Range ( info . location . range . start . line , info . location . range . start . character , info . location . range . end . line , info . location . range . end . character ) ; diagnostic . relatedInformation . push ( new vscode . DiagnosticRelatedInformation ( new vscode . Location ( vscode . Uri . parse ( info . location . uri ) , infoRange ) , info . message ) ) ; } } diagnosticsIntelliSense . push ( diagnostic ) ; } ) ; const realUri = vscode . Uri . parse ( params . uri ) ; diagnosticsCollectionIntelliSense . set ( realUri , diagnosticsIntelliSense ) ; clientCollection . timeTelemetryCollector . setUpdateRangeTime ( realUri ) ; } function publishCodeAnalysisDiagnostics ( params ) { if ( ! diagnosticsCollectionCodeAnalysis ) { diagnosticsCollectionCodeAnalysis = vscode . languages . createDiagnosticCollection ( "clang-tidy" ) ; } const diagnosticsCodeAnalysis = [ ] ; params . diagnostics . forEach ( ( d ) => { const message = util . getLocalizedString ( d . localizeStringParams ) ; const r = new vscode . Range ( d . range . start . line , d . range . start . character , d . range . end . line , d . range . end . character ) ; const diagnostic = new vscode . Diagnostic ( r , message , d . severity ) ; if ( typeof d . code === "string" && d . code . length !== 0 && ! d . code . startsWith ( "clang-diagnostic-" ) ) { const codes = d . code . split ( ',' ) ; let codeIndex = codes . length - 1 ; if ( codes [ codeIndex ] === "cert-dcl51-cpp" ) { codeIndex = 0 ; } diagnostic . code = { value : d . code , target : vscode . Uri . parse ( `https://releases.llvm.org/13.0.0/tools/clang/tools/extra/docs/clang-tidy/checks/${ codes [ codeIndex ] }.html` ) } ; } else { diagnostic . code = d . code ; } diagnostic . source = "C/C++" ; if ( d . relatedInformation ) { diagnostic . relatedInformation = [ ] ; for ( const info of d . relatedInformation ) { const infoRange = new vscode . Range ( info . location . range . start . line , info . location . range . start . character , info . location . range . end . line , info . location . range . end . character ) ; diagnostic . relatedInformation . push ( new vscode . DiagnosticRelatedInformation ( new vscode . Location ( vscode . Uri . parse ( info . location . uri ) , infoRange ) , info . message ) ) ; } } diagnosticsCodeAnalysis . push ( diagnostic ) ; } ) ; const realUri = vscode . Uri . parse ( params . uri ) ; diagnosticsCollectionCodeAnalysis . set ( realUri , diagnosticsCodeAnalysis ) ; } interface WorkspaceFolderParams { workspaceFolderUri ? : string ; } interface TelemetryPayload { event : string ; properties ? : { [ key ] : string ; } ; metrics ? : { [ key ] : number ; } ; } interface DebugProtocolParams { jsonrpc : string ; method : string ; params ? : any ; } interface ReportStatusNotificationBody extends WorkspaceFolderParams { status : string ; } interface QueryCompilerDefaultsParams { } interface CppPropertiesParams extends WorkspaceFolderParams { currentConfiguration : number ; configurations : any [ ] ; isReady ? : boolean ; } interface FolderSelectedSettingParams extends WorkspaceFolderParams { currentConfiguration : number ; } interface SwitchHeaderSourceParams extends WorkspaceFolderParams { switchHeaderSourceFileName : string ; } interface FileChangedParams extends WorkspaceFolderParams { uri : string ; } interface InputRegion { startLine : number ; endLine : number ; } interface DecorationRangesPair { decoration : vscode . TextEditorDecorationType ; ranges : vscode . Range [ ] ; } interface InactiveRegionParams { uri : string ; fileVersion : number ; regions : InputRegion [ ] ; } interface SourceFileConfigurationItemAdapter { uri : string ; configuration : SourceFileConfiguration ; } interface CustomConfigurationParams extends WorkspaceFolderParams { configurationItems : SourceFileConfigurationItemAdapter [ ] ; } interface CustomBrowseConfigurationParams extends WorkspaceFolderParams { browseConfiguration : WorkspaceBrowseConfiguration ; } interface CompileCommandsPaths extends WorkspaceFolderParams { paths : string [ ] ; } interface QueryTranslationUnitSourceParams extends WorkspaceFolderParams { uri : string ; } interface QueryTranslationUnitSourceResult { candidates : string [ ] ; } interface GetDiagnosticsResult { diagnostics : string ; } interface CppDiagnosticRelatedInformation { location : Location ; message : string ; } interface Diagnostic { range : Range ; code ? : number | string ; source ? : string ; severity : vscode . DiagnosticSeverity ; localizeStringParams : LocalizeStringParams ; relatedInformation ? : CppDiagnosticRelatedInformation [ ] ; } interface PublishDiagnosticsParams { uri : string ; diagnostics : Diagnostic [ ] ; } interface GetCodeActionsRequestParams { uri : string ; range : Range ; } interface CodeActionCommand { localizeStringParams : LocalizeStringParams ; command : string ; arguments ? : any [ ] ; edit ? : TextEdit ; } interface ShowMessageWindowParams { type : number ; localizeStringParams : LocalizeStringParams ; } interface ShowWarningParams { localizeStringParams : LocalizeStringParams ; } export interface GetDocumentSymbolRequestParams { uri : string ; } export interface WorkspaceSymbolParams extends WorkspaceFolderParams { query : string ; } export enum SymbolScope { Public = 0 , Protected = 1 , Private = 2 } export interface LocalizeDocumentSymbol { name : string ; detail : LocalizeStringParams ; kind : vscode . SymbolKind ; scope : SymbolScope ; range : Range ; selectionRange : Range ; children : LocalizeDocumentSymbol [ ] ; } /** Differs from vscode.Location, which has a uri of type vscode.Uri. */ interface Location { uri : string ; range : Range ; } export interface LocalizeSymbolInformation { name : string ; kind : vscode . SymbolKind ; scope : SymbolScope ; location : Location ; containerName : string ; suffix : LocalizeStringParams ; } export interface RenameParams { newName : string ; position : Position ; textDocument : TextDocumentIdentifier ; } export interface FindAllReferencesParams { position : Position ; textDocument : TextDocumentIdentifier ; } interface DidChangeConfigurationParams extends WorkspaceFolderParams { settings : any ; } export interface FormatParams { uri : string ; range : Range ; character : string ; insertSpaces : boolean ; tabSize : number ; editorConfigSettings : any ; useVcFormat : boolean ; } interface TextEdit { range : Range ; newText : string ; } export interface GetFoldingRangesParams { uri : string ; id : number ; } export enum FoldingRangeKind { None = 0 , Comment = 1 , Imports = 2 , Region = 3 } export interface CppFoldingRange { kind : FoldingRangeKind ; range : InputRegion ; } export interface GetFoldingRangesResult { canceled : boolean ; ranges : CppFoldingRange [ ] ; } interface AbortRequestParams { id : number ; } export interface GetSemanticTokensParams { uri : string ; id : number ; } interface SemanticToken { line : number ; character : number ; length : number ; type : number ; modifiers ? : number ; } export interface GetSemanticTokensResult { fileVersion : number ; canceled : boolean ; tokens : SemanticToken [ ] ; } enum SemanticTokenTypes { macro = 0 , enumMember = 1 , variable = 2 , parameter = 3 , type = 4 , referenceType = 5 , valueType = 6 , function = 7 , method = 8 , property = 9 , cliProperty = 10 , event = 11 , genericType = 12 , templateFunction = 13 , templateType = 14 , namespace = 15 , label = 16 , customLiteral = 17 , numberLiteral = 18 , stringLiteral = 19 , operatorOverload = 20 , memberOperatorOverload = 21 , newOperator = 22 } enum SemanticTokenModifiers { static = ( 1 << 0 ) , global = ( 1 << 1 ) , local = ( 1 << 2 ) } interface IntelliSenseSetup { uri : string ; } interface GoToDirectiveInGroupParams { uri : string ; position : Position ; next : boolean ; } ; interface SetTemporaryTextDocumentLanguageParams { path : string ; isC : boolean ; isCuda : boolean ; } enum CodeAnalysisScope { ActiveFile , OpenFiles , AllFiles , ClearSquiggles } ; interface IntervalTimerParams { freeMemory : number ; } ; export interface TextDocumentWillSaveParams { textDocument : TextDocumentIdentifier ; reason : vscode . TextDocumentSaveReason ; } const QueryCompilerDefaultsRequest = new RequestType < QueryCompilerDefaultsParams , configs . CompilerDefaults , void , void > ( 'cpptools/queryCompilerDefaults' ) ; const QueryTranslationUnitSourceRequest = new RequestType < QueryTranslationUnitSourceParams , QueryTranslationUnitSourceResult , void , void > ( 'cpptools/queryTranslationUnitSource' ) ; const SwitchHeaderSourceRequest = new RequestType < SwitchHeaderSourceParams , string , void , void > ( 'cpptools/didSwitchHeaderSource' ) ; const GetDiagnosticsRequest = new RequestType < void , GetDiagnosticsResult , void , void > ( 'cpptools/getDiagnostics' ) ; const GetCodeActionsRequest = new RequestType < GetCodeActionsRequestParams , CodeActionCommand [ ] , void , void > ( 'cpptools/getCodeActions' ) ; export const GetDocumentSymbolRequest = new RequestType < GetDocumentSymbolRequestParams , LocalizeDocumentSymbol [ ] , void , void > ( 'cpptools/getDocumentSymbols' ) ; export const GetSymbolInfoRequest = new RequestType < WorkspaceSymbolParams , LocalizeSymbolInformation [ ] , void , void > ( 'cpptools/getWorkspaceSymbols' ) ; export const GetFoldingRangesRequest = new RequestType < GetFoldingRangesParams , GetFoldingRangesResult , void , void > ( 'cpptools/getFoldingRanges' ) ; export const GetSemanticTokensRequest = new RequestType < GetSemanticTokensParams , GetSemanticTokensResult , void , void > ( 'cpptools/getSemanticTokens' ) ; export const FormatDocumentRequest = new RequestType < FormatParams , TextEdit [ ] , void , void > ( 'cpptools/formatDocument' ) ; export const FormatRangeRequest = new RequestType < FormatParams , TextEdit [ ] , void , void > ( 'cpptools/formatRange' ) ; export const FormatOnTypeRequest = new RequestType < FormatParams , TextEdit [ ] , void , void > ( 'cpptools/formatOnType' ) ; const GoToDirectiveInGroupRequest = new RequestType < GoToDirectiveInGroupParams , Position | undefined , void , void > ( 'cpptools/goToDirectiveInGroup' ) ; const DidOpenNotification = new NotificationType < DidOpenTextDocumentParams , void > ( 'textDocument/didOpen' ) ; const FileCreatedNotification = new NotificationType < FileChangedParams , void > ( 'cpptools/fileCreated' ) ; const FileChangedNotification = new NotificationType < FileChangedParams , void > ( 'cpptools/fileChanged' ) ; const FileDeletedNotification = new NotificationType < FileChangedParams , void > ( 'cpptools/fileDeleted' ) ; const ResetDatabaseNotification = new NotificationType < void , void > ( 'cpptools/resetDatabase' ) ; const PauseParsingNotification = new NotificationType < void , void > ( 'cpptools/pauseParsing' ) ; const ResumeParsingNotification = new NotificationType < void , void > ( 'cpptools/resumeParsing' ) ; const PauseCodeAnalysisNotification = new NotificationType < void , void > ( 'cpptools/pauseCodeAnalysis' ) ; const ResumeCodeAnalysisNotification = new NotificationType < void , void > ( 'cpptools/resumeCodeAnalysis' ) ; const CancelCodeAnalysisNotification = new NotificationType < void , void > ( 'cpptools/cancelCodeAnalysis' ) ; const ActiveDocumentChangeNotification = new NotificationType < TextDocumentIdentifier , void > ( 'cpptools/activeDocumentChange' ) ; const RestartIntelliSenseForFileNotification = new NotificationType < TextDocumentIdentifier , void > ( 'cpptools/restartIntelliSenseForFile' ) ; const TextEditorSelectionChangeNotification = new NotificationType < Range , void > ( 'cpptools/textEditorSelectionChange' ) ; const ChangeCppPropertiesNotification = new NotificationType < CppPropertiesParams , void > ( 'cpptools/didChangeCppProperties' ) ; const ChangeCompileCommandsNotification = new NotificationType < FileChangedParams , void > ( 'cpptools/didChangeCompileCommands' ) ; const ChangeSelectedSettingNotification = new NotificationType < FolderSelectedSettingParams , void > ( 'cpptools/didChangeSelectedSetting' ) ; const IntervalTimerNotification = new NotificationType < IntervalTimerParams , void > ( 'cpptools/onIntervalTimer' ) ; const CustomConfigurationNotification = new NotificationType < CustomConfigurationParams , void > ( 'cpptools/didChangeCustomConfiguration' ) ; const CustomBrowseConfigurationNotification = new NotificationType < CustomBrowseConfigurationParams , void > ( 'cpptools/didChangeCustomBrowseConfiguration' ) ; const ClearCustomConfigurationsNotification = new NotificationType < WorkspaceFolderParams , void > ( 'cpptools/clearCustomConfigurations' ) ; const ClearCustomBrowseConfigurationNotification = new NotificationType < WorkspaceFolderParams , void > ( 'cpptools/clearCustomBrowseConfiguration' ) ; const RescanFolderNotification = new NotificationType < void , void > ( 'cpptools/rescanFolder' ) ; export const RequestReferencesNotification = new NotificationType < boolean , void > ( 'cpptools/requestReferences' ) ; export const CancelReferencesNotification = new NotificationType < void , void > ( 'cpptools/cancelReferences' ) ; const FinishedRequestCustomConfig = new NotificationType < string , void > ( 'cpptools/finishedRequestCustomConfig' ) ; const FindAllReferencesNotification = new NotificationType < FindAllReferencesParams , void > ( 'cpptools/findAllReferences' ) ; const RenameNotification = new NotificationType < RenameParams , void > ( 'cpptools/rename' ) ; const DidChangeSettingsNotification = new NotificationType < DidChangeConfigurationParams , void > ( 'cpptools/didChangeSettings' ) ; const AbortRequestNotification = new NotificationType < AbortRequestParams , void > ( 'cpptools/abortRequest' ) ; const CodeAnalysisNotification = new NotificationType < CodeAnalysisScope , void > ( 'cpptools/runCodeAnalysis' ) ; const ReloadWindowNotification = new NotificationType < void , void > ( 'cpptools/reloadWindow' ) ; const LogTelemetryNotification = new NotificationType < TelemetryPayload , void > ( 'cpptools/logTelemetry' ) ; const ReportTagParseStatusNotification = new NotificationType < LocalizeStringParams , void > ( 'cpptools/reportTagParseStatus' ) ; const ReportStatusNotification = new NotificationType < ReportStatusNotificationBody , void > ( 'cpptools/reportStatus' ) ; const DebugProtocolNotification = new NotificationType < DebugProtocolParams , void > ( 'cpptools/debugProtocol' ) ; const DebugLogNotification = new NotificationType < LocalizeStringParams , void > ( 'cpptools/debugLog' ) ; const InactiveRegionNotification = new NotificationType < InactiveRegionParams , void > ( 'cpptools/inactiveRegions' ) ; const CompileCommandsPathsNotification = new NotificationType < CompileCommandsPaths , void > ( 'cpptools/compileCommandsPaths' ) ; const ReferencesNotification = new NotificationType < refs . ReferencesResultMessage , void > ( 'cpptools/references' ) ; const ReportReferencesProgressNotification = new NotificationType < refs . ReportReferencesProgressNotification , void > ( 'cpptools/reportReferencesProgress' ) ; const RequestCustomConfig = new NotificationType < string , void > ( 'cpptools/requestCustomConfig' ) ; const PublishDiagnosticsNotification = new NotificationType < PublishDiagnosticsParams , void > ( 'cpptools/publishDiagnostics' ) ; const PublishCodeAnalysisDiagnosticsNotification = new NotificationType < PublishDiagnosticsParams , void > ( 'cpptools/publishCodeAnalysisDiagnostics' ) ; const ShowMessageWindowNotification = new NotificationType < ShowMessageWindowParams , void > ( 'cpptools/showMessageWindow' ) ; const ShowWarningNotification = new NotificationType < ShowWarningParams , void > ( 'cpptools/showWarning' ) ; const ReportTextDocumentLanguage = new NotificationType < string , void > ( 'cpptools/reportTextDocumentLanguage' ) ; const SemanticTokensChanged = new NotificationType < string , void > ( 'cpptools/semanticTokensChanged' ) ; const IntelliSenseSetupNotification = new NotificationType < IntelliSenseSetup , void > ( 'cpptools/IntelliSenseSetup' ) ; const SetTemporaryTextDocumentLanguageNotification = new NotificationType < SetTemporaryTextDocumentLanguageParams , void > ( 'cpptools/setTemporaryTextDocumentLanguage' ) ; const ReportCodeAnalysisProcessedNotification = new NotificationType < number , void > ( 'cpptools/reportCodeAnalysisProcessed' ) ; const ReportCodeAnalysisTotalNotification = new NotificationType < number , void > ( 'cpptools/reportCodeAnalysisTotal' ) ; let failureMessageShown = false ; export interface ReferencesCancellationState { reject ( ) : void ; callback ( ) : void ; } class ClientModel { public isParsingWorkspace : DataBinding < boolean > ; public isParsingWorkspacePausable : DataBinding < boolean > ; public isParsingWorkspacePaused : DataBinding < boolean > ; public isParsingFiles : DataBinding < boolean > ; public isUpdatingIntelliSense : DataBinding < boolean > ; public isRunningCodeAnalysis : DataBinding < boolean > ; public isCodeAnalysisPaused : DataBinding < boolean > ; public codeAnalysisProcessed : DataBinding < number > ; public codeAnalysisTotal : DataBinding < number > ; public referencesCommandMode : DataBinding < refs . ReferencesCommandMode > ; public parsingWorkspaceStatus : DataBinding < string > ; public activeConfigName : DataBinding < string > ; constructor ( ) { this . isParsingWorkspace = new DataBinding < boolean > ( false ) ; this . isParsingWorkspacePausable = new DataBinding < boolean > ( false ) ; this . isParsingWorkspacePaused = new DataBinding < boolean > ( false ) ; this . isParsingFiles = new DataBinding < boolean > ( false ) ; this . isUpdatingIntelliSense = new DataBinding < boolean > ( false ) ; this . isRunningCodeAnalysis = new DataBinding < boolean > ( false ) ; this . isCodeAnalysisPaused = new DataBinding < boolean > ( false ) ; this . codeAnalysisProcessed = new DataBinding < number > ( 0 ) ; this . codeAnalysisTotal = new DataBinding < number > ( 0 ) ; this . referencesCommandMode = new DataBinding < refs . ReferencesCommandMode > ( refs . ReferencesCommandMode . None ) ; this . parsingWorkspaceStatus = new DataBinding < string > ( "" ) ; this . activeConfigName = new DataBinding < string > ( "" ) ; } public activate ( ) { this . isParsingWorkspace . activate ( ) ; this . isParsingWorkspacePausable . activate ( ) ; this . isParsingWorkspacePaused . activate ( ) ; this . isParsingFiles . activate ( ) ; this . isUpdatingIntelliSense . activate ( ) ; this . isRunningCodeAnalysis . activate ( ) ; this . isCodeAnalysisPaused . activate ( ) ; this . codeAnalysisProcessed . activate ( ) ; this . codeAnalysisTotal . activate ( ) ; this . referencesCommandMode . activate ( ) ; this . parsingWorkspaceStatus . activate ( ) ; this . activeConfigName . activate ( ) ; } public deactivate ( ) { this . isParsingWorkspace . deactivate ( ) ; this . isParsingWorkspacePausable . deactivate ( ) ; this . isParsingWorkspacePaused . deactivate ( ) ; this . isParsingFiles . deactivate ( ) ; this . isUpdatingIntelliSense . deactivate ( ) ; this . isRunningCodeAnalysis . deactivate ( ) ; this . isCodeAnalysisPaused . deactivate ( ) ; this . codeAnalysisProcessed . deactivate ( ) ; this . codeAnalysisTotal . deactivate ( ) ; this . referencesCommandMode . deactivate ( ) ; this . parsingWorkspaceStatus . deactivate ( ) ; this . activeConfigName . deactivate ( ) ; } public dispose ( ) { this . isParsingWorkspace . dispose ( ) ; this . isParsingWorkspacePausable . dispose ( ) ; this . isParsingWorkspacePaused . dispose ( ) ; this . isParsingFiles . dispose ( ) ; this . isUpdatingIntelliSense . dispose ( ) ; this . isRunningCodeAnalysis . dispose ( ) ; this . isCodeAnalysisPaused . dispose ( ) ; this . codeAnalysisProcessed . dispose ( ) ; this . codeAnalysisTotal . dispose ( ) ; this . referencesCommandMode . dispose ( ) ; this . parsingWorkspaceStatus . dispose ( ) ; this . activeConfigName . dispose ( ) ; } } export interface Client { ParsingWorkspaceChanged : vscode . Event < boolean > ; ParsingWorkspacePausableChanged : vscode . Event < boolean > ; ParsingWorkspacePausedChanged : vscode . Event < boolean > ; ParsingFilesChanged : vscode . Event < boolean > ; IntelliSenseParsingChanged : vscode . Event < boolean > ; RunningCodeAnalysisChanged : vscode . Event < boolean > ; CodeAnalysisPausedChanged : vscode . Event < boolean > ; CodeAnalysisProcessedChanged : vscode . Event < number > ; CodeAnalysisTotalChanged : vscode . Event < number > ; ReferencesCommandModeChanged : vscode . Event < refs . ReferencesCommandMode > ; TagParserStatusChanged : vscode . Event < string > ; ActiveConfigChanged : vscode . Event < string > ; RootPath : string ; RootRealPath : string ; RootUri ? : vscode . Uri ; Name : string ; TrackedDocuments : Set < vscode . TextDocument > ; onDidChangeSettings ( event , isFirstClient ) : { [ key ] : string ; } ; onDidOpenTextDocument ( document ) : void ; onDidCloseTextDocument ( document ) : void ; onDidChangeVisibleTextEditor ( editor ) : void ; onDidChangeTextDocument ( textDocumentChangeEvent ) : void ; onRegisterCustomConfigurationProvider ( provider ) : Thenable < void > ; updateCustomConfigurations ( requestingProvider ? ) : Thenable < void > ; updateCustomBrowseConfiguration ( requestingProvider ? ) : Thenable < void > ; provideCustomConfiguration ( docUri , requestFile ? ) : Promise < void > ; logDiagnostics ( ) : Promise < void > ; rescanFolder ( ) : Promise < void > ; toggleReferenceResultsView ( ) : void ; setCurrentConfigName ( configurationName ) : Thenable < void > ; getCurrentConfigName ( ) : Thenable < string | undefined > ; getCurrentConfigCustomVariable ( variableName ) : Thenable < string > ; getVcpkgInstalled ( ) : Thenable < boolean > ; getVcpkgEnabled ( ) : Thenable < boolean > ; getCurrentCompilerPathAndArgs ( ) : Thenable < util . CompilerPathAndArgs | undefined > ; getKnownCompilers ( ) : Thenable < configs . KnownCompiler [ ] | undefined > ; takeOwnership ( document ) : void ; queueTask < T > ( task ) : Promise < T > ; requestWhenReady < T > ( request ) : Thenable < T > ; notifyWhenLanguageClientReady ( notify ) : void ; awaitUntilLanguageClientReady ( ) : void ; requestSwitchHeaderSource ( rootPath , fileName ) : Thenable < string > ; activeDocumentChanged ( document ) : Promise < void > ; restartIntelliSenseForFile ( document ) : Promise < void > ; activate ( ) : void ; selectionChanged ( selection ) : void ; resetDatabase ( ) : void ; deactivate ( ) : void ; pauseParsing ( ) : void ; resumeParsing ( ) : void ; PauseCodeAnalysis ( ) : void ; ResumeCodeAnalysis ( ) : void ; CancelCodeAnalysis ( ) : void ; handleConfigurationSelectCommand ( ) : Promise < void > ; handleConfigurationProviderSelectCommand ( ) : Promise < void > ; handleShowParsingCommands ( ) : Promise < void > ; handleShowCodeAnalysisCommands ( ) : Promise < void > ; handleReferencesIcon ( ) : void ; handleConfigurationEditCommand ( viewColumn ? ) : void ; handleConfigurationEditJSONCommand ( viewColumn ? ) : void ; handleConfigurationEditUICommand ( viewColumn ? ) : void ; handleAddToIncludePathCommand ( path ) : void ; handleGoToDirectiveInGroup ( next ) : Promise < void > ; handleCheckForCompiler ( ) : Promise < void > ; handleRunCodeAnalysisOnActiveFile ( ) : Promise < void > ; handleRunCodeAnalysisOnOpenFiles ( ) : Promise < void > ; handleRunCodeAnalysisOnAllFiles ( ) : Promise < void > ; handleClearCodeAnalysisSquiggles ( ) : Promise < void > ; onInterval ( ) : void ; dispose ( ) : void ; addFileAssociations ( fileAssociations , languageId ) : void ; sendDidChangeSettings ( settings ) : void ; } export function createClient ( allClients , workspaceFolder ? ) { return new DefaultClient ( allClients , workspaceFolder ) ; } export function createNullClient ( ) { return new NullClient ( ) ; } export class DefaultClient implements Client { private innerLanguageClient ? : LanguageClient ; private disposables : vscode . Disposable [ ] = [ ] ; private documentFormattingProviderDisposable : vscode . Disposable | undefined ; private formattingRangeProviderDisposable : vscode . Disposable | undefined ; private onTypeFormattingProviderDisposable : vscode . Disposable | undefined ; private codeFoldingProvider : FoldingRangeProvider | undefined ; private codeFoldingProviderDisposable : vscode . Disposable | undefined ; private semanticTokensProvider : SemanticTokensProvider | undefined ; private semanticTokensProviderDisposable : vscode . Disposable | undefined ; private innerConfiguration ? : configs . CppProperties ; private rootPathFileWatcher ? : vscode . FileSystemWatcher ; private rootFolder ? : vscode . WorkspaceFolder ; private rootRealPath : string ; private storagePath : string ; private trackedDocuments = new Set < vscode . TextDocument > ( ) ; private isSupported : boolean = true ; private inactiveRegionsDecorations = new Map < string , DecorationRangesPair > ( ) ; private settingsTracker : SettingsTracker ; private loggingLevel : string | undefined ; private configurationProvider ? : string ; private documentSelector : DocumentFilter [ ] = [ { scheme : 'file' , language : 'c' } , { scheme : 'file' , language : 'cpp' } , { scheme : 'file' , language : 'cuda-cpp' } ] ; public semanticTokensLegend : vscode . SemanticTokensLegend | undefined ; public static abortRequestId : number = 0 ; public static referencesParams : RenameParams | FindAllReferencesParams | undefined ; public static referencesRequestPending : boolean = false ; public static referencesPendingCancellations : ReferencesCancellationState [ ] = [ ] ; public static renameRequestsPending : number = 0 ; public static renamePending : boolean = false ; private model : ClientModel = new ClientModel ( ) ; public get ParsingWorkspaceChanged ( ) : vscode . Event < boolean > { return this . model . isParsingWorkspace . ValueChanged ; } public get ParsingWorkspacePausableChanged ( ) : vscode . Event < boolean > { return this . model . isParsingWorkspacePausable . ValueChanged ; } public get ParsingWorkspacePausedChanged ( ) : vscode . Event < boolean > { return this . model . isParsingWorkspacePaused . ValueChanged ; } public get ParsingFilesChanged ( ) : vscode . Event < boolean > { return this . model . isParsingFiles . ValueChanged ; } public get IntelliSenseParsingChanged ( ) : vscode . Event < boolean > { return this . model . isUpdatingIntelliSense . ValueChanged ; } public get RunningCodeAnalysisChanged ( ) : vscode . Event < boolean > { return this . model . isRunningCodeAnalysis . ValueChanged ; } public get CodeAnalysisPausedChanged ( ) : vscode . Event < boolean > { return this . model . isCodeAnalysisPaused . ValueChanged ; } public get CodeAnalysisProcessedChanged ( ) : vscode . Event < number > { return this . model . codeAnalysisProcessed . ValueChanged ; } public get CodeAnalysisTotalChanged ( ) : vscode . Event < number > { return this . model . codeAnalysisTotal . ValueChanged ; } public get ReferencesCommandModeChanged ( ) : vscode . Event < refs . ReferencesCommandMode > { return this . model . referencesCommandMode . ValueChanged ; } public get TagParserStatusChanged ( ) : vscode . Event < string > { return this . model . parsingWorkspaceStatus . ValueChanged ; } public get ActiveConfigChanged ( ) : vscode . Event < string > { return this . model . activeConfigName . ValueChanged ; } /**
     * don't use this.rootFolder directly since it can be undefined
     */ public get RootPath ( ) : string { return ( this . rootFolder ) ? this . rootFolder . uri . fsPath : "" ; } public get RootRealPath ( ) : string { return this . rootRealPath ; } public get RootUri ( ) : vscode . Uri | undefined { return ( this . rootFolder ) ? this . rootFolder . uri : undefined ; } public get RootFolder ( ) : vscode . WorkspaceFolder | undefined { return this . rootFolder ; } public get Name ( ) : string { return this . getName ( this . rootFolder ) ; } public get TrackedDocuments ( ) : Set < vscode . TextDocument > { return this . trackedDocuments ; } public get IsTagParsing ( ) : boolean { return this . model . isParsingWorkspace . Value || this . model . isParsingFiles . Value ; } public get ReferencesCommandMode ( ) : refs . ReferencesCommandMode { return this . model . referencesCommandMode . Value ; } public get languageClient ( ) : LanguageClient { if ( ! this . innerLanguageClient ) { throw new Error ( "Attempting to use languageClient before initialized" ) ; } return this . innerLanguageClient ; } private get configuration ( ) : configs . CppProperties { if ( ! this . innerConfiguration ) { throw new Error ( "Attempting to use configuration before initialized" ) ; } return this . innerConfiguration ; } private get AdditionalEnvironment ( ) : { [ key ] : string | string [ ] ; } { return { workspaceFolderBasename : this . Name , workspaceStorage : this . storagePath , execPath : process . execPath , pathSeparator : ( os . platform ( ) === 'win32' ) ? "\\" : "/" } ; } private getName ( workspaceFolder ? ) { return workspaceFolder ? workspaceFolder . name : "untitled" ; } see requestWhenReady see notifyWhenLanguageClientReady see awaitUntilLanguageClientReady constructor ( allClients , workspaceFolder ? ) { this . rootFolder = workspaceFolder ; this . rootRealPath = this . RootPath ? ( fs . existsSync ( this . RootPath ) ? fs . realpathSync ( this . RootPath ) : this . RootPath ) : "" ; let storagePath ; if ( util . extensionContext ) { const path = util . extensionContext . storageUri ?. fsPath ; if ( path ) { storagePath = path ; } } if ( ! storagePath ) { storagePath = this . RootPath ? path . join ( this . RootPath , "/.vscode" ) : "" ; } if ( workspaceFolder && vscode . workspace . workspaceFolders && vscode . workspace . workspaceFolders . length > 1 ) { storagePath = path . join ( storagePath , util . getUniqueWorkspaceStorageName ( workspaceFolder ) ) ; } this . storagePath = storagePath ; const rootUri = this . RootUri ; this . settingsTracker = getTracker ( rootUri ) ; try { let firstClient = false ; if ( ! languageClient || languageClientCrashedNeedsRestart ) { if ( languageClientCrashedNeedsRestart ) { languageClientCrashedNeedsRestart = false ; } languageClient = this . createLanguageClient ( allClients ) ; clientCollection = allClients ; languageClient . registerProposedFeatures ( ) ; languageClient . start ( ) ; util . setProgress ( util . getProgressExecutableStarted ( ) ) ; firstClient = true ; } ui = getUI ( ) ; ui . bind ( this ) ; this . queueBlockingTask ( async ( ) => { await languageClient . onReady ( ) ; try { const workspaceFolder = this . rootFolder ; this . innerConfiguration = new configs . CppProperties ( rootUri , workspaceFolder ) ; this . innerConfiguration . ConfigurationsChanged ( ( e ) => this . onConfigurationsChanged ( e ) ) ; this . innerConfiguration . SelectionChanged ( ( e ) => this . onSelectedConfigurationChanged ( e ) ) ; this . innerConfiguration . CompileCommandsChanged ( ( e ) => this . onCompileCommandsChanged ( e ) ) ; this . disposables . push ( this . innerConfiguration ) ; this . innerLanguageClient = languageClient ; telemetry . logLanguageServerEvent ( "NonDefaultInitialCppSettings" , this . settingsTracker . getUserModifiedSettings ( ) ) ; failureMessageShown = false ; class CodeActionProvider implements vscode . CodeActionProvider { private client : DefaultClient ; constructor ( client ) { this . client = client ; } public async provideCodeActions ( document , range , context , token ) { return this . client . requestWhenReady ( async ( ) => { let r ; if ( range instanceof vscode . Selection ) { if ( range . active . isBefore ( range . anchor ) ) { r = Range . create ( Position . create ( range . active . line , range . active . character ) , Position . create ( range . anchor . line , range . anchor . character ) ) ; } else { r = Range . create ( Position . create ( range . anchor . line , range . anchor . character ) , Position . create ( range . active . line , range . active . character ) ) ; } } else { r = Range . create ( Position . create ( range . start . line , range . start . character ) , Position . create ( range . end . line , range . end . character ) ) ; } const params = { range : r , uri : document . uri . toString ( ) } ; const commands = await this . client . languageClient . sendRequest ( GetCodeActionsRequest , params ) ; const resultCodeActions = [ ] ; commands . forEach ( ( command ) => { const title = util . getLocalizedString ( command . localizeStringParams ) ; let edit ; if ( command . edit ) { edit = new vscode . WorkspaceEdit ( ) ; edit . replace ( document . uri , new vscode . Range ( new vscode . Position ( command . edit . range . start . line , command . edit . range . start . character ) , new vscode . Position ( command . edit . range . end . line , command . edit . range . end . character ) ) , command . edit . newText ) ; } const vscodeCodeAction = { title : title , command : command . command === "edit" ? undefined : { title : title , command : command . command , arguments : command . arguments } , edit : edit , kind : edit === undefined ? vscode . CodeActionKind . QuickFix : vscode . CodeActionKind . RefactorInline } ; resultCodeActions . push ( vscodeCodeAction ) ; } ) ; return resultCodeActions ; } ) ; } } const tokenTypesLegend = [ ] ; for ( const e in SemanticTokenTypes ) { if ( isNaN ( Number ( e ) ) ) { tokenTypesLegend . push ( e ) ; } } const tokenModifiersLegend = [ ] ; for ( const e in SemanticTokenModifiers ) { if ( isNaN ( Number ( e ) ) ) { tokenModifiersLegend . push ( e ) ; } } this . semanticTokensLegend = new vscode . SemanticTokensLegend ( tokenTypesLegend , tokenModifiersLegend ) ; if ( firstClient ) { workspaceReferences = new refs . ReferencesManager ( this ) ; const inputCompilerDefaults = await languageClient . sendRequest ( QueryCompilerDefaultsRequest , { } ) ; compilerDefaults = inputCompilerDefaults ; this . configuration . CompilerDefaults = compilerDefaults ; registerCommands ( ) ; this . registerFileWatcher ( ) ; this . disposables . push ( vscode . languages . registerRenameProvider ( this . documentSelector , new RenameProvider ( this ) ) ) ; this . disposables . push ( vscode . languages . registerReferenceProvider ( this . documentSelector , new FindAllReferencesProvider ( this ) ) ) ; this . disposables . push ( vscode . languages . registerWorkspaceSymbolProvider ( new WorkspaceSymbolProvider ( this ) ) ) ; this . disposables . push ( vscode . languages . registerDocumentSymbolProvider ( this . documentSelector , new DocumentSymbolProvider ( this ) , undefined ) ) ; this . disposables . push ( vscode . languages . registerCodeActionsProvider ( this . documentSelector , new CodeActionProvider ( this ) , undefined ) ) ; const settings = new CppSettings ( ) ; if ( settings . formattingEngine !== "Disabled" ) { this . documentFormattingProviderDisposable = vscode . languages . registerDocumentFormattingEditProvider ( this . documentSelector , new DocumentFormattingEditProvider ( this ) ) ; this . formattingRangeProviderDisposable = vscode . languages . registerDocumentRangeFormattingEditProvider ( this . documentSelector , new DocumentRangeFormattingEditProvider ( this ) ) ; this . onTypeFormattingProviderDisposable = vscode . languages . registerOnTypeFormattingEditProvider ( this . documentSelector , new OnTypeFormattingEditProvider ( this ) , ";" , "}" , "\n" ) ; } if ( settings . codeFolding ) { this . codeFoldingProvider = new FoldingRangeProvider ( this ) ; this . codeFoldingProviderDisposable = vscode . languages . registerFoldingRangeProvider ( this . documentSelector , this . codeFoldingProvider ) ; } if ( settings . enhancedColorization && this . semanticTokensLegend ) { this . semanticTokensProvider = new SemanticTokensProvider ( this ) ; this . semanticTokensProviderDisposable = vscode . languages . registerDocumentSemanticTokensProvider ( this . documentSelector , this . semanticTokensProvider , this . semanticTokensLegend ) ; } this . registerNotifications ( ) ; } else { this . configuration . CompilerDefaults = compilerDefaults ; } } catch ( err ) { this . isSupported = false ; if ( ! failureMessageShown ) { failureMessageShown = true ; vscode . window . showErrorMessage ( localize ( "unable.to.start" , "Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: {0}" , String ( err ) ) ) ; } } } ) ; } catch ( errJS ) { const err = errJS as NodeJS . ErrnoException ; this . isSupported = false ; if ( ! failureMessageShown ) { failureMessageShown = true ; let additionalInfo ; if ( err . code === "EPERM" ) { additionalInfo = localize ( 'check.permissions' , "EPERM: Check permissions for '{0}'" , getLanguageServerFileName ( ) ) ; } else { additionalInfo = String ( err ) ; } vscode . window . showErrorMessage ( localize ( "unable.to.start" , "Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: {0}" , additionalInfo ) ) ; } } } public sendFindAllReferencesNotification ( params ) { this . languageClient . sendNotification ( FindAllReferencesNotification , params ) ; } public sendRenameNofication ( params ) { this . languageClient . sendNotification ( RenameNotification , params ) ; } private createLanguageClient ( allClients ) { const serverModule = getLanguageServerFileName ( ) ; const exeExists = fs . existsSync ( serverModule ) ; if ( ! exeExists ) { telemetry . logLanguageServerEvent ( "missingLanguageServerBinary" ) ; throw String ( 'Missing binary at ' + serverModule ) ; } const serverName = this . getName ( this . rootFolder ) ; const serverOptions = { run : { command : serverModule } , debug : { command : serverModule , args : [ serverName ] } } ; const settings_clangFormatPath = [ ] ; const settings_clangFormatStyle = [ ] ; const settings_clangFormatFallbackStyle = [ ] ; const settings_clangFormatSortIncludes = [ ] ; const settings_codeAnalysisExclude = [ ] ; const settings_codeAnalysisRunAutomatically = [ ] ; const settings_clangTidyEnabled = [ ] ; const settings_clangTidyPath = [ ] ; const settings_clangTidyConfig = [ ] ; const settings_clangTidyFallbackConfig = [ ] ; const settings_clangTidyFixWarnings = [ ] ; const settings_clangTidyFixErrors = [ ] ; const settings_clangTidyFixNotes = [ ] ; const settings_clangTidyHeaderFilter = [ ] ; const settings_clangTidyArgs = [ ] ; const settings_clangTidyChecksEnabled = [ ] ; const settings_clangTidyChecksDisabled = [ ] ; const settings_filesEncoding = [ ] ; const settings_cppFilesExclude = [ ] ; const settings_filesExclude = [ ] ; const settings_filesAutoSaveAfterDelay = [ ] ; const settings_searchExclude = [ ] ; const settings_editorAutoClosingBrackets = [ ] ; const settings_intelliSenseEngine = [ ] ; const settings_intelliSenseEngineFallback = [ ] ; const settings_errorSquiggles = [ ] ; const settings_dimInactiveRegions = [ ] ; const settings_enhancedColorization = [ ] ; const settings_suggestSnippets = [ ] ; const settings_exclusionPolicy = [ ] ; const settings_preferredPathSeparator = [ ] ; const settings_defaultSystemIncludePath = [ ] ; const settings_intelliSenseCachePath = [ ] ; const settings_intelliSenseCacheSize = [ ] ; const settings_intelliSenseMemoryLimit = [ ] ; const settings_autocomplete = [ ] ; const settings_autocompleteAddParentheses = [ ] ; const workspaceSettings = new CppSettings ( ) ; const workspaceOtherSettings = new OtherSettings ( ) ; const settings_indentBraces = [ ] ; const settings_indentMultiLine = [ ] ; const settings_indentWithinParentheses = [ ] ; const settings_indentPreserveWithinParentheses = [ ] ; const settings_indentCaseLabels = [ ] ; const settings_indentCaseContents = [ ] ; const settings_indentCaseContentsWhenBlock = [ ] ; const settings_indentLambdaBracesWhenParameter = [ ] ; const settings_indentGotoLabels = [ ] ; const settings_indentPreprocessor = [ ] ; const settings_indentAccessSpecifiers = [ ] ; const settings_indentNamespaceContents = [ ] ; const settings_indentPreserveComments = [ ] ; const settings_newLineBeforeOpenBraceNamespace = [ ] ; const settings_newLineBeforeOpenBraceType = [ ] ; const settings_newLineBeforeOpenBraceFunction = [ ] ; const settings_newLineBeforeOpenBraceBlock = [ ] ; const settings_newLineBeforeOpenBraceLambda = [ ] ; const settings_newLineScopeBracesOnSeparateLines = [ ] ; const settings_newLineCloseBraceSameLineEmptyType = [ ] ; const settings_newLineCloseBraceSameLineEmptyFunction = [ ] ; const settings_newLineBeforeCatch = [ ] ; const settings_newLineBeforeElse = [ ] ; const settings_newLineBeforeWhileInDoWhile = [ ] ; const settings_spaceBeforeFunctionOpenParenthesis = [ ] ; const settings_spaceWithinParameterListParentheses = [ ] ; const settings_spaceBetweenEmptyParameterListParentheses = [ ] ; const settings_spaceAfterKeywordsInControlFlowStatements = [ ] ; const settings_spaceWithinControlFlowStatementParentheses = [ ] ; const settings_spaceBeforeLambdaOpenParenthesis = [ ] ; const settings_spaceWithinCastParentheses = [ ] ; const settings_spaceSpaceAfterCastCloseParenthesis = [ ] ; const settings_spaceWithinExpressionParentheses = [ ] ; const settings_spaceBeforeBlockOpenBrace = [ ] ; const settings_spaceBetweenEmptyBraces = [ ] ; const settings_spaceBeforeInitializerListOpenBrace = [ ] ; const settings_spaceWithinInitializerListBraces = [ ] ; const settings_spacePreserveInInitializerList = [ ] ; const settings_spaceBeforeOpenSquareBracket = [ ] ; const settings_spaceWithinSquareBrackets = [ ] ; const settings_spaceBeforeEmptySquareBrackets = [ ] ; const settings_spaceBetweenEmptySquareBrackets = [ ] ; const settings_spaceGroupSquareBrackets = [ ] ; const settings_spaceWithinLambdaBrackets = [ ] ; const settings_spaceBetweenEmptyLambdaBrackets = [ ] ; const settings_spaceBeforeComma = [ ] ; const settings_spaceAfterComma = [ ] ; const settings_spaceRemoveAroundMemberOperators = [ ] ; const settings_spaceBeforeInheritanceColon = [ ] ; const settings_spaceBeforeConstructorColon = [ ] ; const settings_spaceRemoveBeforeSemicolon = [ ] ; const settings_spaceInsertAfterSemicolon = [ ] ; const settings_spaceRemoveAroundUnaryOperator = [ ] ; const settings_spaceAroundBinaryOperator = [ ] ; const settings_spaceAroundAssignmentOperator = [ ] ; const settings_spacePointerReferenceAlignment = [ ] ; const settings_spaceAroundTernaryOperator = [ ] ; const settings_wrapPreserveBlocks = [ ] ; { const settings = [ ] ; const otherSettings = [ ] ; if ( vscode . workspace . workspaceFolders && vscode . workspace . workspaceFolders . length > 0 ) { for ( const workspaceFolder of vscode . workspace . workspaceFolders ) { settings . push ( new CppSettings ( workspaceFolder . uri ) ) ; otherSettings . push ( new OtherSettings ( workspaceFolder . uri ) ) ; } } else { settings . push ( workspaceSettings ) ; otherSettings . push ( workspaceOtherSettings ) ; } for ( const setting of settings ) { settings_clangFormatPath . push ( util . resolveVariables ( setting . clangFormatPath , this . AdditionalEnvironment ) ) ; settings_codeAnalysisExclude . push ( setting . codeAnalysisExclude ) ; settings_codeAnalysisRunAutomatically . push ( setting . codeAnalysisRunAutomatically ) ; settings_clangTidyEnabled . push ( setting . clangTidyEnabled ) ; settings_clangTidyPath . push ( util . resolveVariables ( setting . clangTidyPath , this . AdditionalEnvironment ) ) ; settings_clangTidyConfig . push ( setting . clangTidyConfig ) ; settings_clangTidyFallbackConfig . push ( setting . clangTidyFallbackConfig ) ; settings_clangTidyFixWarnings . push ( setting . clangTidyFixWarnings ) ; settings_clangTidyFixErrors . push ( setting . clangTidyFixErrors ) ; settings_clangTidyFixNotes . push ( setting . clangTidyFixNotes ) ; settings_clangTidyHeaderFilter . push ( setting . clangTidyHeaderFilter ) ; settings_clangTidyArgs . push ( setting . clangTidyArgs ) ; settings_clangTidyChecksEnabled . push ( setting . clangTidyChecksEnabled ) ; settings_clangTidyChecksDisabled . push ( setting . clangTidyChecksDisabled ) ; settings_indentBraces . push ( setting . vcFormatIndentBraces ) ; settings_indentWithinParentheses . push ( setting . vcFormatIndentWithinParentheses ) ; settings_indentPreserveWithinParentheses . push ( setting . vcFormatIndentPreserveWithinParentheses ) ; settings_indentMultiLine . push ( setting . vcFormatIndentMultiLineRelativeTo ) ; settings_indentCaseLabels . push ( setting . vcFormatIndentCaseLabels ) ; settings_indentCaseContents . push ( setting . vcFormatIndentCaseContents ) ; settings_indentCaseContentsWhenBlock . push ( setting . vcFormatIndentCaseContentsWhenBlock ) ; settings_indentLambdaBracesWhenParameter . push ( setting . vcFormatIndentLambdaBracesWhenParameter ) ; settings_indentGotoLabels . push ( setting . vcFormatIndentGotoLables ) ; settings_indentPreprocessor . push ( setting . vcFormatIndentPreprocessor ) ; settings_indentAccessSpecifiers . push ( setting . vcFormatIndentAccessSpecifiers ) ; settings_indentNamespaceContents . push ( setting . vcFormatIndentNamespaceContents ) ; settings_indentPreserveComments . push ( setting . vcFormatIndentPreserveComments ) ; settings_newLineBeforeOpenBraceNamespace . push ( setting . vcFormatNewlineBeforeOpenBraceNamespace ) ; settings_newLineBeforeOpenBraceType . push ( setting . vcFormatNewlineBeforeOpenBraceType ) ; settings_newLineBeforeOpenBraceFunction . push ( setting . vcFormatNewlineBeforeOpenBraceFunction ) ; settings_newLineBeforeOpenBraceBlock . push ( setting . vcFormatNewlineBeforeOpenBraceBlock ) ; settings_newLineScopeBracesOnSeparateLines . push ( setting . vcFormatNewlineScopeBracesOnSeparateLines ) ; settings_newLineBeforeOpenBraceLambda . push ( setting . vcFormatNewlineBeforeOpenBraceLambda ) ; settings_newLineCloseBraceSameLineEmptyType . push ( setting . vcFormatNewlineCloseBraceSameLineEmptyType ) ; settings_newLineCloseBraceSameLineEmptyFunction . push ( setting . vcFormatNewlineCloseBraceSameLineEmptyFunction ) ; settings_newLineBeforeCatch . push ( setting . vcFormatNewlineBeforeCatch ) ; settings_newLineBeforeElse . push ( setting . vcFormatNewlineBeforeElse ) ; settings_newLineBeforeWhileInDoWhile . push ( setting . vcFormatNewlineBeforeWhileInDoWhile ) ; settings_spaceBeforeFunctionOpenParenthesis . push ( setting . vcFormatSpaceBeforeFunctionOpenParenthesis ) ; settings_spaceWithinParameterListParentheses . push ( setting . vcFormatSpaceWithinParameterListParentheses ) ; settings_spaceBetweenEmptyParameterListParentheses . push ( setting . vcFormatSpaceBetweenEmptyParameterListParentheses ) ; settings_spaceAfterKeywordsInControlFlowStatements . push ( setting . vcFormatSpaceAfterKeywordsInControlFlowStatements ) ; settings_spaceWithinControlFlowStatementParentheses . push ( setting . vcFormatSpaceWithinControlFlowStatementParentheses ) ; settings_spaceBeforeLambdaOpenParenthesis . push ( setting . vcFormatSpaceBeforeLambdaOpenParenthesis ) ; settings_spaceWithinCastParentheses . push ( setting . vcFormatSpaceWithinCastParentheses ) ; settings_spaceSpaceAfterCastCloseParenthesis . push ( setting . vcFormatSpaceAfterCastCloseParenthesis ) ; settings_spaceWithinExpressionParentheses . push ( setting . vcFormatSpaceWithinExpressionParentheses ) ; settings_spaceBeforeBlockOpenBrace . push ( setting . vcFormatSpaceBeforeBlockOpenBrace ) ; settings_spaceBetweenEmptyBraces . push ( setting . vcFormatSpaceBetweenEmptyBraces ) ; settings_spaceBeforeInitializerListOpenBrace . push ( setting . vcFormatSpaceBeforeInitializerListOpenBrace ) ; settings_spaceWithinInitializerListBraces . push ( setting . vcFormatSpaceWithinInitializerListBraces ) ; settings_spacePreserveInInitializerList . push ( setting . vcFormatSpacePreserveInInitializerList ) ; settings_spaceBeforeOpenSquareBracket . push ( setting . vcFormatSpaceBeforeOpenSquareBracket ) ; settings_spaceWithinSquareBrackets . push ( setting . vcFormatSpaceWithinSquareBrackets ) ; settings_spaceBeforeEmptySquareBrackets . push ( setting . vcFormatSpaceBeforeEmptySquareBrackets ) ; settings_spaceBetweenEmptySquareBrackets . push ( setting . vcFormatSpaceBetweenEmptySquareBrackets ) ; settings_spaceGroupSquareBrackets . push ( setting . vcFormatSpaceGroupSquareBrackets ) ; settings_spaceWithinLambdaBrackets . push ( setting . vcFormatSpaceWithinLambdaBrackets ) ; settings_spaceBetweenEmptyLambdaBrackets . push ( setting . vcFormatSpaceBetweenEmptyLambdaBrackets ) ; settings_spaceBeforeComma . push ( setting . vcFormatSpaceBeforeComma ) ; settings_spaceAfterComma . push ( setting . vcFormatSpaceAfterComma ) ; settings_spaceRemoveAroundMemberOperators . push ( setting . vcFormatSpaceRemoveAroundMemberOperators ) ; settings_spaceBeforeInheritanceColon . push ( setting . vcFormatSpaceBeforeInheritanceColon ) ; settings_spaceBeforeConstructorColon . push ( setting . vcFormatSpaceBeforeConstructorColon ) ; settings_spaceRemoveBeforeSemicolon . push ( setting . vcFormatSpaceRemoveBeforeSemicolon ) ; settings_spaceInsertAfterSemicolon . push ( setting . vcFormatSpaceInsertAfterSemicolon ) ; settings_spaceRemoveAroundUnaryOperator . push ( setting . vcFormatSpaceRemoveAroundUnaryOperator ) ; settings_spaceAroundBinaryOperator . push ( setting . vcFormatSpaceAroundBinaryOperator ) ; settings_spaceAroundAssignmentOperator . push ( setting . vcFormatSpaceAroundAssignmentOperator ) ; settings_spacePointerReferenceAlignment . push ( setting . vcFormatSpacePointerReferenceAlignment ) ; settings_spaceAroundTernaryOperator . push ( setting . vcFormatSpaceAroundTernaryOperator ) ; settings_wrapPreserveBlocks . push ( setting . vcFormatWrapPreserveBlocks ) ; settings_clangFormatStyle . push ( setting . clangFormatStyle ) ; settings_clangFormatFallbackStyle . push ( setting . clangFormatFallbackStyle ) ; settings_clangFormatSortIncludes . push ( setting . clangFormatSortIncludes ) ; settings_intelliSenseEngine . push ( setting . intelliSenseEngine ) ; settings_intelliSenseEngineFallback . push ( setting . intelliSenseEngineFallback ) ; settings_errorSquiggles . push ( setting . errorSquiggles ) ; settings_dimInactiveRegions . push ( setting . dimInactiveRegions ) ; settings_enhancedColorization . push ( workspaceSettings . enhancedColorization ? "Enabled" : "Disabled" ) ; settings_suggestSnippets . push ( setting . suggestSnippets ) ; settings_exclusionPolicy . push ( setting . exclusionPolicy ) ; settings_preferredPathSeparator . push ( setting . preferredPathSeparator ) ; settings_defaultSystemIncludePath . push ( setting . defaultSystemIncludePath ) ; settings_intelliSenseCachePath . push ( util . resolveCachePath ( setting . intelliSenseCachePath , this . AdditionalEnvironment ) ) ; settings_intelliSenseCacheSize . push ( setting . intelliSenseCacheSize ) ; settings_intelliSenseMemoryLimit . push ( setting . intelliSenseMemoryLimit ) ; settings_autocomplete . push ( setting . autocomplete ) ; settings_autocompleteAddParentheses . push ( setting . autocompleteAddParentheses ) ; settings_cppFilesExclude . push ( setting . filesExclude ) ; } for ( const otherSetting of otherSettings ) { settings_filesEncoding . push ( otherSetting . filesEncoding ) ; settings_filesExclude . push ( otherSetting . filesExclude ) ; settings_filesAutoSaveAfterDelay . push ( otherSetting . filesAutoSaveAfterDelay ) ; settings_searchExclude . push ( otherSetting . searchExclude ) ; settings_editorAutoClosingBrackets . push ( otherSetting . editorAutoClosingBrackets ) ; } } let intelliSenseCacheDisabled = false ; if ( os . platform ( ) === "darwin" ) { const releaseParts = os . release ( ) . split ( "." ) ; if ( releaseParts . length >= 1 ) { intelliSenseCacheDisabled = parseInt ( releaseParts [ 0 ] ) < 17 ; } } const localizedStrings = [ ] ; for ( let i = 0 ; i < localizedStringCount ; i ++ ) { localizedStrings . push ( lookupString ( i ) ) ; } const clientOptions = { documentSelector : [ { scheme : 'file' , language : 'c' } , { scheme : 'file' , language : 'cpp' } , { scheme : 'file' , language : 'cuda-cpp' } ] , initializationOptions : { freeMemory : os . freemem ( ) / 1048576 , maxConcurrentThreads : workspaceSettings . maxConcurrentThreads , maxCachedProcesses : workspaceSettings . maxCachedProcesses , maxMemory : workspaceSettings . maxMemory , intelliSense : { maxCachedProcesses : workspaceSettings . intelliSenseMaxCachedProcesses , maxMemory : workspaceSettings . intelliSenseMaxMemory } , references : { maxConcurrentThreads : workspaceSettings . referencesMaxConcurrentThreads , maxCachedProcesses : workspaceSettings . referencesMaxCachedProcesses , maxMemory : workspaceSettings . referencesMaxMemory } , codeAnalysis : { maxConcurrentThreads : workspaceSettings . codeAnalysisMaxConcurrentThreads , maxMemory : workspaceSettings . codeAnalysisMaxMemory , updateDelay : workspaceSettings . codeAnalysisUpdateDelay , exclude : settings_codeAnalysisExclude , runAutomatically : settings_codeAnalysisRunAutomatically , clangTidy : { enabled : settings_clangTidyEnabled , path : settings_clangTidyPath , config : settings_clangTidyConfig , fallbackConfig : settings_clangTidyFallbackConfig , fix : { warnings : settings_clangTidyFixWarnings , errors : settings_clangTidyFixErrors , notes : settings_clangTidyFixNotes } , headerFilter : settings_clangTidyHeaderFilter , args : settings_clangTidyArgs , checks : { enabled : settings_clangTidyChecksEnabled , disabled : settings_clangTidyChecksDisabled } } } , clang_format_path : settings_clangFormatPath , clang_format_style : settings_clangFormatStyle , vcFormat : { indent : { braces : settings_indentBraces , multiLineRelativeTo : settings_indentMultiLine , withinParentheses : settings_indentWithinParentheses , preserveWithinParentheses : settings_indentPreserveWithinParentheses , caseLabels : settings_indentCaseLabels , caseContents : settings_indentCaseContents , caseContentsWhenBlock : settings_indentCaseContentsWhenBlock , lambdaBracesWhenParameter : settings_indentLambdaBracesWhenParameter , gotoLabels : settings_indentGotoLabels , preprocessor : settings_indentPreprocessor , accesSpecifiers : settings_indentAccessSpecifiers , namespaceContents : settings_indentNamespaceContents , preserveComments : settings_indentPreserveComments } , newLine : { beforeOpenBrace : { namespace : settings_newLineBeforeOpenBraceNamespace , type : settings_newLineBeforeOpenBraceType , function : settings_newLineBeforeOpenBraceFunction , block : settings_newLineBeforeOpenBraceBlock , lambda : settings_newLineBeforeOpenBraceLambda } , scopeBracesOnSeparateLines : settings_newLineScopeBracesOnSeparateLines , closeBraceSameLine : { emptyType : settings_newLineCloseBraceSameLineEmptyType , emptyFunction : settings_newLineCloseBraceSameLineEmptyFunction } , beforeCatch : settings_newLineBeforeCatch , beforeElse : settings_newLineBeforeElse , beforeWhileInDoWhile : settings_newLineBeforeWhileInDoWhile } , space : { beforeFunctionOpenParenthesis : settings_spaceBeforeFunctionOpenParenthesis , withinParameterListParentheses : settings_spaceWithinParameterListParentheses , betweenEmptyParameterListParentheses : settings_spaceBetweenEmptyParameterListParentheses , afterKeywordsInControlFlowStatements : settings_spaceAfterKeywordsInControlFlowStatements , withinControlFlowStatementParentheses : settings_spaceWithinControlFlowStatementParentheses , beforeLambdaOpenParenthesis : settings_spaceBeforeLambdaOpenParenthesis , withinCastParentheses : settings_spaceWithinCastParentheses , afterCastCloseParenthesis : settings_spaceSpaceAfterCastCloseParenthesis , withinExpressionParentheses : settings_spaceWithinExpressionParentheses , beforeBlockOpenBrace : settings_spaceBeforeBlockOpenBrace , betweenEmptyBraces : settings_spaceBetweenEmptyBraces , beforeInitializerListOpenBrace : settings_spaceBeforeInitializerListOpenBrace , withinInitializerListBraces : settings_spaceWithinInitializerListBraces , preserveInInitializerList : settings_spacePreserveInInitializerList , beforeOpenSquareBracket : settings_spaceBeforeOpenSquareBracket , withinSquareBrackets : settings_spaceWithinSquareBrackets , beforeEmptySquareBrackets : settings_spaceBeforeEmptySquareBrackets , betweenEmptySquareBrackets : settings_spaceBetweenEmptySquareBrackets , groupSquareBrackets : settings_spaceGroupSquareBrackets , withinLambdaBrackets : settings_spaceWithinLambdaBrackets , betweenEmptyLambdaBrackets : settings_spaceBetweenEmptyLambdaBrackets , beforeComma : settings_spaceBeforeComma , afterComma : settings_spaceAfterComma , removeAroundMemberOperators : settings_spaceRemoveAroundMemberOperators , beforeInheritanceColon : settings_spaceBeforeInheritanceColon , beforeConstructorColon : settings_spaceBeforeConstructorColon , removeBeforeSemicolon : settings_spaceRemoveBeforeSemicolon , insertAfterSemicolon : settings_spaceInsertAfterSemicolon , removeAroundUnaryOperator : settings_spaceRemoveAroundUnaryOperator , aroundBinaryOperator : settings_spaceAroundBinaryOperator , aroundAssignmentOperator : settings_spaceAroundAssignmentOperator , pointerReferenceAlignment : settings_spacePointerReferenceAlignment , aroundTernaryOperator : settings_spaceAroundTernaryOperator } , wrap : { preserveBlocks : settings_wrapPreserveBlocks } } , clang_format_fallbackStyle : settings_clangFormatFallbackStyle , clang_format_sortIncludes : settings_clangFormatSortIncludes , extension_path : util . extensionPath , files : { encoding : settings_filesEncoding , autoSaveAfterDelay : settings_filesAutoSaveAfterDelay } , editor : { autoClosingBrackets : settings_editorAutoClosingBrackets } , workspace_fallback_encoding : workspaceOtherSettings . filesEncoding , cpp_exclude_files : settings_cppFilesExclude , exclude_files : settings_filesExclude , exclude_search : settings_searchExclude , associations : workspaceOtherSettings . filesAssociations , storage_path : this . storagePath , intelliSenseEngine : settings_intelliSenseEngine , intelliSenseEngineFallback : settings_intelliSenseEngineFallback , intelliSenseCacheDisabled : intelliSenseCacheDisabled , intelliSenseCachePath : settings_intelliSenseCachePath , intelliSenseCacheSize : settings_intelliSenseCacheSize , intelliSenseMemoryLimit : settings_intelliSenseMemoryLimit , intelliSenseUpdateDelay : workspaceSettings . intelliSenseUpdateDelay , autocomplete : settings_autocomplete , autocompleteAddParentheses : settings_autocompleteAddParentheses , errorSquiggles : settings_errorSquiggles , dimInactiveRegions : settings_dimInactiveRegions , enhancedColorization : settings_enhancedColorization , suggestSnippets : settings_suggestSnippets , simplifyStructuredComments : workspaceSettings . simplifyStructuredComments , loggingLevel : workspaceSettings . loggingLevel , workspaceParsingPriority : workspaceSettings . workspaceParsingPriority , workspaceSymbols : workspaceSettings . workspaceSymbols , exclusionPolicy : settings_exclusionPolicy , preferredPathSeparator : settings_preferredPathSeparator , default : { systemIncludePath : settings_defaultSystemIncludePath } , vcpkg_root : util . getVcpkgRoot ( ) , experimentalFeatures : workspaceSettings . experimentalFeatures , edgeMessagesDirectory : path . join ( util . getExtensionFilePath ( "bin" ) , "messages" , util . getLocaleId ( ) ) , localizedStrings : localizedStrings , packageVersion : util . packageJson . version } , middleware : createProtocolFilter ( allClients ) , errorHandler : { error : ( ) => ErrorAction . Continue , closed : ( ) => { languageClientCrashTimes . push ( Date . now ( ) ) ; languageClientCrashedNeedsRestart = true ; telemetry . logLanguageServerEvent ( "languageClientCrash" ) ; if ( languageClientCrashTimes . length < 5 ) { allClients . forEach ( client => { allClients . replace ( client , true ) ; } ) ; } else { const elapsed = languageClientCrashTimes [ languageClientCrashTimes . length - 1 ] - languageClientCrashTimes [ 0 ] ; if ( elapsed <= 3 * 60 * 1000 ) { vscode . window . showErrorMessage ( localize ( 'server.crashed2' , "The language server crashed 5 times in the last 3 minutes. It will not be restarted." ) ) ; allClients . forEach ( client => { allClients . replace ( client , false ) ; } ) ; } else { languageClientCrashTimes . shift ( ) ; allClients . forEach ( client => { allClients . replace ( client , true ) ; } ) ; } } return CloseAction . DoNotRestart ; } } } ; this . loggingLevel = clientOptions . initializationOptions . loggingLevel ; return new LanguageClient ( `cpptools` , serverOptions , clientOptions ) ; } public sendAllSettings ( ) { const cppSettingsScoped = { } ; { const cppSettingsResourceScoped = vscode . workspace . getConfiguration ( "C_Cpp" , this . RootUri ) ; const cppSettingsNonScoped = vscode . workspace . getConfiguration ( "C_Cpp" ) ; for ( const key in cppSettingsResourceScoped ) { const curSetting = util . packageJson . contributes . configuration . properties [ "C_Cpp." + key ] ; if ( curSetting === undefined ) { continue ; } const settings = ( curSetting . scope === "resource" || curSetting . scope === "machine-overridable" ) ? cppSettingsResourceScoped : cppSettingsNonScoped ; cppSettingsScoped [ key ] = settings . get ( key ) ; } cppSettingsScoped [ "default" ] = { systemIncludePath : cppSettingsResourceScoped . get ( "default.systemIncludePath" ) } ; } const otherSettingsFolder = new OtherSettings ( this . RootUri ) ; const otherSettingsWorkspace = new OtherSettings ( ) ; const clangTidyConfig = vscode . workspace . getConfiguration ( "C_Cpp.codeAnalysis.clangTidy" , this . RootUri ) ; const settings = { C_Cpp : { ... cppSettingsScoped , clang_format_path : util . resolveVariables ( cppSettingsScoped . clang_format_path , this . AdditionalEnvironment ) , intelliSenseCachePath : util . resolveCachePath ( cppSettingsScoped . intelliSenseCachePath , this . AdditionalEnvironment ) , codeAnalysis : { ... vscode . workspace . getConfiguration ( "C_Cpp.codeAnalysis" , this . RootUri ) , clangTidy : { ... clangTidyConfig , path : util . resolveVariables ( clangTidyConfig . path , this . AdditionalEnvironment ) , fix : { ... vscode . workspace . getConfiguration ( "C_Cpp.codeAnalysis.clangTidy.fix" , this . RootUri ) } , checks : { ... vscode . workspace . getConfiguration ( "C_Cpp.codeAnalysis.clangTidy.checks" , this . RootUri ) } } } , files : { exclude : vscode . workspace . getConfiguration ( "C_Cpp.files.exclude" , this . RootUri ) } , intelliSense : { ... vscode . workspace . getConfiguration ( "C_Cpp.intelliSense" , this . RootUri ) } , references : { ... vscode . workspace . getConfiguration ( "C_Cpp.references" , this . RootUri ) } , vcFormat : { ... vscode . workspace . getConfiguration ( "C_Cpp.vcFormat" , this . RootUri ) , indent : vscode . workspace . getConfiguration ( "C_Cpp.vcFormat.indent" , this . RootUri ) , newLine : { ... vscode . workspace . getConfiguration ( "C_Cpp.vcFormat.newLine" , this . RootUri ) , beforeOpenBrace : vscode . workspace . getConfiguration ( "C_Cpp.vcFormat.newLine.beforeOpenBrace" , this . RootUri ) , closeBraceSameLine : vscode . workspace . getConfiguration ( "C_Cpp.vcFormat.newLine.closeBraceSameLine" , this . RootUri ) } , space : vscode . workspace . getConfiguration ( "C_Cpp.vcFormat.space" , this . RootUri ) , wrap : vscode . workspace . getConfiguration ( "C_Cpp.vcFormat.wrap" , this . RootUri ) } } , editor : { autoClosingBrackets : otherSettingsFolder . editorAutoClosingBrackets } , files : { encoding : otherSettingsFolder . filesEncoding , exclude : vscode . workspace . getConfiguration ( "files.exclude" , this . RootUri ) , associations : new OtherSettings ( ) . filesAssociations , autoSaveAfterDelay : otherSettingsFolder . filesAutoSaveAfterDelay } , workspace_fallback_encoding : otherSettingsWorkspace . filesEncoding , search : { exclude : vscode . workspace . getConfiguration ( "search.exclude" , this . RootUri ) } } ; this . sendDidChangeSettings ( settings ) ; } public sendDidChangeSettings ( settings ) { this . notifyWhenLanguageClientReady ( ( ) => { this . languageClient . sendNotification ( DidChangeSettingsNotification , { settings , workspaceFolderUri : this . RootPath } ) ; } ) ; } public onDidChangeSettings ( event , isFirstClient ) { this . sendAllSettings ( ) ; const changedSettings = this . settingsTracker . getChangedSettings ( ) ; this . notifyWhenLanguageClientReady ( ( ) => { if ( Object . keys ( changedSettings ) . length > 0 ) { if ( isFirstClient ) { if ( changedSettings [ "commentContinuationPatterns" ] ) { updateLanguageConfigurations ( ) ; } if ( changedSettings [ "loggingLevel" ] ) { const oldLoggingLevelLogged = ! ! this . loggingLevel && this . loggingLevel !== "None" && this . loggingLevel !== "Error" ; const newLoggingLevel = changedSettings [ "loggingLevel" ] ; this . loggingLevel = newLoggingLevel ; const newLoggingLevelLogged = ! ! newLoggingLevel && newLoggingLevel !== "None" && newLoggingLevel !== "Error" ; if ( oldLoggingLevelLogged || newLoggingLevelLogged ) { const out = logger . getOutputChannelLogger ( ) ; out . appendLine ( localize ( { key : "loggingLevel.changed" , comment : [ "{0} is the setting name 'loggingLevel', {1} is a string value such as 'Debug'" ] } , "{0} has changed to: {1}" , "loggingLevel" , changedSettings [ "loggingLevel" ] ) ) ; } } const settings = new CppSettings ( ) ; if ( changedSettings [ "formatting" ] ) { const folderSettings = new CppSettings ( this . RootUri ) ; if ( folderSettings . formattingEngine !== "Disabled" ) { if ( ! this . documentFormattingProviderDisposable ) { this . documentFormattingProviderDisposable = vscode . languages . registerDocumentFormattingEditProvider ( this . documentSelector , new DocumentFormattingEditProvider ( this ) ) ; } if ( ! this . formattingRangeProviderDisposable ) { this . formattingRangeProviderDisposable = vscode . languages . registerDocumentRangeFormattingEditProvider ( this . documentSelector , new DocumentRangeFormattingEditProvider ( this ) ) ; } if ( ! this . onTypeFormattingProviderDisposable ) { this . onTypeFormattingProviderDisposable = vscode . languages . registerOnTypeFormattingEditProvider ( this . documentSelector , new OnTypeFormattingEditProvider ( this ) , ";" , "}" , "\n" ) ; } } else { if ( this . documentFormattingProviderDisposable ) { this . documentFormattingProviderDisposable . dispose ( ) ; this . documentFormattingProviderDisposable = undefined ; } if ( this . formattingRangeProviderDisposable ) { this . formattingRangeProviderDisposable . dispose ( ) ; this . formattingRangeProviderDisposable = undefined ; } if ( this . onTypeFormattingProviderDisposable ) { this . onTypeFormattingProviderDisposable . dispose ( ) ; this . onTypeFormattingProviderDisposable = undefined ; } } } if ( changedSettings [ "codeFolding" ] ) { if ( settings . codeFolding ) { this . codeFoldingProvider = new FoldingRangeProvider ( this ) ; this . codeFoldingProviderDisposable = vscode . languages . registerFoldingRangeProvider ( this . documentSelector , this . codeFoldingProvider ) ; } else if ( this . codeFoldingProviderDisposable ) { this . codeFoldingProviderDisposable . dispose ( ) ; this . codeFoldingProviderDisposable = undefined ; this . codeFoldingProvider = undefined ; } } if ( changedSettings [ "enhancedColorization" ] ) { if ( settings . enhancedColorization && this . semanticTokensLegend ) { this . semanticTokensProvider = new SemanticTokensProvider ( this ) ; this . semanticTokensProviderDisposable = vscode . languages . registerDocumentSemanticTokensProvider ( this . documentSelector , this . semanticTokensProvider , this . semanticTokensLegend ) ; } else if ( this . semanticTokensProviderDisposable ) { this . semanticTokensProviderDisposable . dispose ( ) ; this . semanticTokensProviderDisposable = undefined ; this . semanticTokensProvider = undefined ; } } if ( changedSettings [ "addNodeAddonIncludePaths" ] && settings . addNodeAddonIncludePaths && this . configuration . nodeAddonIncludesFound ( ) === 0 ) { util . promptForReloadWindowDueToSettingsChange ( ) ; } } this . configuration . onDidChangeSettings ( ) ; telemetry . logLanguageServerEvent ( "CppSettingsChange" , changedSettings , undefined ) ; } } ) ; return changedSettings ; } public onDidChangeVisibleTextEditor ( editor ) { const settings = new CppSettings ( this . RootUri ) ; if ( settings . dimInactiveRegions ) { const valuePair = this . inactiveRegionsDecorations . get ( editor . document . uri . toString ( ) ) ; if ( valuePair ) { editor . setDecorations ( valuePair . decoration , valuePair . ranges ) ; } } } public onDidChangeTextDocument ( textDocumentChangeEvent ) { if ( textDocumentChangeEvent . document . uri . scheme === "file" ) { if ( textDocumentChangeEvent . document . languageId === "c" || textDocumentChangeEvent . document . languageId === "cpp" || textDocumentChangeEvent . document . languageId === "cuda-cpp" ) { if ( DefaultClient . renamePending ) { this . cancelReferences ( ) ; } const oldVersion = openFileVersions . get ( textDocumentChangeEvent . document . uri . toString ( ) ) ; const newVersion = textDocumentChangeEvent . document . version ; if ( oldVersion === undefined || newVersion > oldVersion ) { openFileVersions . set ( textDocumentChangeEvent . document . uri . toString ( ) , newVersion ) ; } } } } public onDidOpenTextDocument ( document ) { if ( document . uri . scheme === "file" ) { const uri = document . uri . toString ( ) ; openFileVersions . set ( uri , document . version ) ; } } public onDidCloseTextDocument ( document ) { const uri = document . uri . toString ( ) ; if ( this . semanticTokensProvider ) { this . semanticTokensProvider . invalidateFile ( uri ) ; } openFileVersions . delete ( uri ) ; } private registeredProviders : CustomConfigurationProvider1 [ ] = [ ] ; public onRegisterCustomConfigurationProvider ( provider ) { const onRegistered = ( ) => { if ( provider . version >= Version . v2 ) { this . pauseParsing ( ) ; } } ; return this . notifyWhenLanguageClientReady ( ( ) => { if ( this . registeredProviders . includes ( provider ) ) { return ; } this . registeredProviders . push ( provider ) ; const rootFolder = this . RootFolder ; if ( ! rootFolder ) { return ; } this . configuration . handleConfigurationChange ( ) ; const selectedProvider = this . configuration . CurrentConfigurationProvider ; if ( ! selectedProvider ) { const ask = new PersistentFolderState < boolean > ( "Client.registerProvider" , true , rootFolder ) ; if ( ! fs . existsSync ( `${ this . RootPath }/.vscode/c_cpp_properties.json` ) && ! fs . existsSync ( `${ this . RootPath }/.vscode/settings.json` ) ) { ask . Value = true ; } if ( ask . Value ) { ui . showConfigureCustomProviderMessage ( async ( ) => { const message = ( vscode . workspace . workspaceFolders && vscode . workspace . workspaceFolders . length > 1 ) ? localize ( "provider.configure.folder" , "{0} would like to configure IntelliSense for the '{1}' folder." , provider . name , this . Name ) : localize ( "provider.configure.this.folder" , "{0} would like to configure IntelliSense for this folder." , provider . name ) ; const allow = localize ( "allow.button" , "Allow" ) ; const dontAllow = localize ( "dont.allow.button" , "Don't Allow" ) ; const askLater = localize ( "ask.me.later.button" , "Ask Me Later" ) ; return vscode . window . showInformationMessage ( message , allow , dontAllow , askLater ) . then ( async ( result ) => { switch ( result ) { case allow : { await this . configuration . updateCustomConfigurationProvider ( provider . extensionId ) ; onRegistered ( ) ; ask . Value = false ; telemetry . logLanguageServerEvent ( "customConfigurationProvider" , { "providerId" : provider . extensionId } ) ; return true ; } case dontAllow : { ask . Value = false ; break ; } default : { break ; } } return false ; } ) ; } , ( ) => ask . Value = false ) ; } } else if ( isSameProviderExtensionId ( selectedProvider , provider . extensionId ) ) { onRegistered ( ) ; telemetry . logLanguageServerEvent ( "customConfigurationProvider" , { "providerId" : provider . extensionId } ) ; } else if ( selectedProvider === provider . name ) { onRegistered ( ) ; this . configuration . updateCustomConfigurationProvider ( provider . extensionId ) ; } } ) ; } public updateCustomConfigurations ( requestingProvider ? ) { return this . notifyWhenLanguageClientReady ( ( ) => { if ( ! this . configurationProvider ) { this . clearCustomConfigurations ( ) ; return ; } const currentProvider = getCustomConfigProviders ( ) . get ( this . configurationProvider ) ; if ( ! currentProvider ) { this . clearCustomConfigurations ( ) ; return ; } if ( requestingProvider && requestingProvider . extensionId !== currentProvider . extensionId ) { return ; } this . clearCustomConfigurations ( ) ; if ( diagnosticsCollectionCodeAnalysis ) { diagnosticsCollectionCodeAnalysis . clear ( ) ; } this . trackedDocuments . forEach ( document => { this . provideCustomConfiguration ( document . uri , undefined ) ; } ) ; } ) ; } public updateCustomBrowseConfiguration ( requestingProvider ? ) { return this . notifyWhenLanguageClientReady ( ( ) => { if ( ! this . configurationProvider ) { return ; } console . log ( "updateCustomBrowseConfiguration" ) ; const currentProvider = getCustomConfigProviders ( ) . get ( this . configurationProvider ) ; if ( ! currentProvider || ( requestingProvider && requestingProvider . extensionId !== currentProvider . extensionId ) ) { return ; } const tokenSource = new vscode . CancellationTokenSource ( ) ; const task = async ( ) => { if ( this . RootUri && await currentProvider . canProvideBrowseConfigurationsPerFolder ( tokenSource . token ) ) { return ( currentProvider . provideFolderBrowseConfiguration ( this . RootUri , tokenSource . token ) ) ; } if ( await currentProvider . canProvideBrowseConfiguration ( tokenSource . token ) ) { return currentProvider . provideBrowseConfiguration ( tokenSource . token ) ; } if ( currentProvider . version >= Version . v2 ) { console . warn ( "failed to provide browse configuration" ) ; } return null ; } ; let hasCompleted = false ; task ( ) . then ( async ( config ) => { if ( ! config ) { return ; } if ( currentProvider . version < Version . v3 ) { for ( const c of config . browsePath ) { if ( vscode . workspace . getWorkspaceFolder ( vscode . Uri . file ( c ) ) === this . RootFolder ) { this . sendCustomBrowseConfiguration ( config , currentProvider . extensionId ) ; break ; } } } else { this . sendCustomBrowseConfiguration ( config , currentProvider . extensionId ) ; } if ( ! hasCompleted ) { hasCompleted = true ; if ( currentProvider . version >= Version . v2 ) { this . resumeParsing ( ) ; } } } , ( ) => { if ( ! hasCompleted ) { hasCompleted = true ; if ( currentProvider . version >= Version . v2 ) { this . resumeParsing ( ) ; } } } ) ; global . setTimeout ( async ( ) => { if ( ! hasCompleted ) { hasCompleted = true ; this . sendCustomBrowseConfiguration ( null , undefined , true ) ; if ( currentProvider . version >= Version . v2 ) { console . warn ( "Configuration Provider timed out in {0}ms." , configProviderTimeout ) ; this . resumeParsing ( ) ; } } } , configProviderTimeout ) ; } ) ; } public toggleReferenceResultsView ( ) { workspaceReferences . toggleGroupView ( ) ; } public async logDiagnostics ( ) { const response = await this . requestWhenReady ( ( ) => this . languageClient . sendRequest ( GetDiagnosticsRequest , null ) ) ; if ( ! diagnosticsChannel ) { diagnosticsChannel = vscode . window . createOutputChannel ( localize ( "c.cpp.diagnostics" , "C/C++ Diagnostics" ) ) ; workspaceDisposables . push ( diagnosticsChannel ) ; } else { diagnosticsChannel . clear ( ) ; } const header = `-------- Diagnostics - ${ new Date ( ) . toLocaleString ( ) }\n` ; const version = `Version: ${ util . packageJson . version }\n` ; let configJson = "" ; if ( this . configuration . CurrentConfiguration ) { configJson = `Current Configuration:\n${ JSON . stringify ( this . configuration . CurrentConfiguration , null , 4 ) }\n` ; } let configurationLoggingStr = "" ; const tuSearchStart = response . diagnostics . indexOf ( "Translation Unit Mappings:" ) ; if ( tuSearchStart >= 0 ) { const tuSearchEnd = response . diagnostics . indexOf ( "Translation Unit Configurations:" ) ; if ( tuSearchEnd >= 0 && tuSearchEnd > tuSearchStart ) { let tuSearchString = response . diagnostics . substr ( tuSearchStart , tuSearchEnd - tuSearchStart ) ; let tuSearchIndex = tuSearchString . indexOf ( "[" ) ; while ( tuSearchIndex >= 0 ) { const tuMatch = tuSearchString . match ( /\[\s(.*)\s\]/ ) ; if ( tuMatch && tuMatch . length > 1 ) { const tuPath = vscode . Uri . file ( tuMatch [ 1 ] ) . toString ( ) ; if ( this . configurationLogging . has ( tuPath ) ) { if ( configurationLoggingStr . length === 0 ) { configurationLoggingStr += "Custom configurations:\n" ; } configurationLoggingStr += `[ ${ tuMatch [ 1 ] } ]\n${ this . configurationLogging . get ( tuPath ) }\n` ; } } tuSearchString = tuSearchString . substr ( tuSearchIndex + 1 ) ; tuSearchIndex = tuSearchString . indexOf ( "[" ) ; } } } diagnosticsChannel . appendLine ( `${ header }${ version }${ configJson }${ this . browseConfigurationLogging }${ configurationLoggingStr }${ response . diagnostics }` ) ; diagnosticsChannel . show ( false ) ; } public async rescanFolder ( ) { await this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( RescanFolderNotification ) ) ; } public async provideCustomConfiguration ( docUri , requestFile ? ) { const onFinished = ( ) => { if ( requestFile ) { this . languageClient . sendNotification ( FinishedRequestCustomConfig , requestFile ) ; } } ; const providerId = this . configurationProvider ; if ( ! providerId ) { onFinished ( ) ; return ; } const provider = getCustomConfigProviders ( ) . get ( providerId ) ; if ( ! provider ) { onFinished ( ) ; return ; } if ( ! provider . isReady ) { onFinished ( ) ; throw new Error ( `${ this . configurationProvider } is not ready` ) ; } return this . queueBlockingTask ( async ( ) => { const tokenSource = new vscode . CancellationTokenSource ( ) ; console . log ( "provideCustomConfiguration" ) ; const providerName = provider . name ; const params = { uri : docUri . toString ( ) , workspaceFolderUri : this . RootPath } ; const response = await this . languageClient . sendRequest ( QueryTranslationUnitSourceRequest , params ) ; if ( ! response . candidates || response . candidates . length === 0 ) { onFinished ( ) ; return ; } const provideConfigurationAsync = async ( ) => { if ( provider ) { for ( let i = 0 ; i < response . candidates . length ; ++ i ) { try { const candidate = response . candidates [ i ] ; const tuUri = vscode . Uri . parse ( candidate ) ; if ( await provider . canProvideConfiguration ( tuUri , tokenSource . token ) ) { const configs = await provider . provideConfigurations ( [ tuUri ] , tokenSource . token ) ; if ( configs && configs . length > 0 && configs [ 0 ] ) { const fileConfiguration = this . configuration . CurrentConfiguration ; if ( fileConfiguration ?. mergeConfigurations ) { configs . forEach ( config => { if ( fileConfiguration . includePath ) { fileConfiguration . includePath . forEach ( p => { if ( ! config . configuration . includePath . includes ( p ) ) { config . configuration . includePath . push ( p ) ; } } ) ; } if ( fileConfiguration . defines ) { fileConfiguration . defines . forEach ( d => { if ( ! config . configuration . defines . includes ( d ) ) { config . configuration . defines . push ( d ) ; } } ) ; } if ( ! config . configuration . forcedInclude ) { config . configuration . forcedInclude = [ ] ; } if ( fileConfiguration . forcedInclude ) { fileConfiguration . forcedInclude . forEach ( i => { if ( config . configuration . forcedInclude ) { if ( ! config . configuration . forcedInclude . includes ( i ) ) { config . configuration . forcedInclude . push ( i ) ; } } } ) ; } } ) ; } return configs as SourceFileConfigurationItem [ ] ; } } if ( tokenSource . token . isCancellationRequested ) { return null ; } } catch ( err ) { console . warn ( "Caught exception request configuration" ) ; } } } } ; const configs = await this . callTaskWithTimeout ( provideConfigurationAsync , configProviderTimeout , tokenSource ) ; try { if ( configs && configs . length > 0 ) { this . sendCustomConfigurations ( configs , provider . version ) ; } onFinished ( ) ; } catch ( err ) { if ( requestFile ) { onFinished ( ) ; return ; } const settings = new CppSettings ( this . RootUri ) ; if ( settings . configurationWarnings === "Enabled" && ! this . isExternalHeader ( docUri ) && ! vscode . debug . activeDebugSession ) { const dismiss = localize ( "dismiss.button" , "Dismiss" ) ; const disable = localize ( "diable.warnings.button" , "Disable Warnings" ) ; const configName = this . configuration . CurrentConfiguration ?. name ; if ( ! configName ) { return ; } let message = localize ( "unable.to.provide.configuration" , "{0} is unable to provide IntelliSense configuration information for '{1}'. Settings from the '{2}' configuration will be used instead." , providerName , docUri . fsPath , configName ) ; if ( err ) { message += ` (${ err })` ; } vscode . window . showInformationMessage ( message , dismiss , disable ) . then ( response => { switch ( response ) { case disable : { settings . toggleSetting ( "configurationWarnings" , "Enabled" , "Disabled" ) ; break ; } } } ) ; } } } ) ; } private async handleRequestCustomConfig ( requestFile ) { await this . provideCustomConfiguration ( vscode . Uri . file ( requestFile ) , requestFile ) ; } private isExternalHeader ( uri ) { const rootUri = this . RootUri ; return ! rootUri || ( util . isHeader ( uri ) && ! uri . toString ( ) . startsWith ( rootUri . toString ( ) ) ) ; } public getCurrentConfigName ( ) { return this . queueTask ( ( ) => Promise . resolve ( this . configuration . CurrentConfiguration ?. name ) ) ; } public getCurrentConfigCustomVariable ( variableName ) { return this . queueTask ( ( ) => Promise . resolve ( this . configuration . CurrentConfiguration ?. customConfigurationVariables ?. [ variableName ] || '' ) ) ; } public setCurrentConfigName ( configurationName ) { return this . queueTask ( ( ) => new Promise ( ( resolve , reject ) => { const configurations = this . configuration . Configurations || [ ] ; const configurationIndex = configurations . findIndex ( ( config ) => config . name === configurationName ) ; if ( configurationIndex !== - 1 ) { this . configuration . select ( configurationIndex ) ; resolve ( ) ; } else { reject ( new Error ( localize ( "config.not.found" , "The requested configuration name is not found: {0}" , configurationName ) ) ) ; } } ) ) ; } public getCurrentCompilerPathAndArgs ( ) { return this . queueTask ( ( ) => Promise . resolve ( util . extractCompilerPathAndArgs ( this . configuration . CurrentConfiguration ?. compilerPath , this . configuration . CurrentConfiguration ?. compilerArgs ) ) ) ; } public getVcpkgInstalled ( ) { return this . queueTask ( ( ) => Promise . resolve ( this . configuration . VcpkgInstalled ) ) ; } public getVcpkgEnabled ( ) { const cppSettings = new CppSettings ( this . RootUri ) ; return Promise . resolve ( cppSettings . vcpkgEnabled === true ) ; } public getKnownCompilers ( ) { return this . queueTask ( ( ) => Promise . resolve ( this . configuration . KnownCompiler ) ) ; } /**
     * Take ownership of a document that was previously serviced by another client.
     * This process involves sending a textDocument/didOpen message to the server so
     * that it knows about the file, as well as adding it to this client's set of
     * tracked documents.
     */ public takeOwnership ( document ) { const params = { textDocument : { uri : document . uri . toString ( ) , languageId : document . languageId , version : document . version , text : document . getText ( ) } } ; this . updateActiveDocumentTextOptions ( ) ; this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( DidOpenNotification , params ) ) ; this . trackedDocuments . add ( document ) ; } /**
     * wait until the all pendingTasks are complete (e.g. language client is ready for use)
     * before attempting to send messages or operate on the client.
     */ public async queueTask < T > ( task ) { if ( this . isSupported ) { const nextTask = async ( ) => { try { return await task ( ) ; } catch ( err ) { console . error ( err ) ; throw err ; } } ; if ( pendingTask && ! pendingTask . Done ) { try { await pendingTask . getPromise ( ) ; } catch ( e ) { } } else { pendingTask = undefined ; } return nextTask ( ) ; } else { throw new Error ( localize ( "unsupported.client" , "Unsupported client" ) ) ; } } param task private async queueBlockingTask < T > ( task ) { if ( this . isSupported ) { pendingTask = new util . BlockingTask < T > ( task , pendingTask ) ; return pendingTask . getPromise ( ) ; } else { throw new Error ( localize ( "unsupported.client" , "Unsupported client" ) ) ; } } private callTaskWithTimeout < T > ( task , ms , cancelToken ? ) { let timer ; const timeout = ( ) => new Promise < T > ( ( resolve , reject ) => { timer = global . setTimeout ( ( ) => { clearTimeout ( timer ) ; if ( cancelToken ) { cancelToken . cancel ( ) ; } reject ( localize ( "timed.out" , "Timed out in {0}ms." , ms ) ) ; } , ms ) ; } ) ; return Promise . race ( [ task ( ) , timeout ( ) ] ) . then ( ( result ) => { clearTimeout ( timer ) ; return result ; } , ( error ) => { clearTimeout ( timer ) ; throw error ; } ) ; } public requestWhenReady < T > ( request ) { return this . queueTask ( request ) ; } public notifyWhenLanguageClientReady < T > ( notify ) { const task = ( ) => new Promise < T > ( resolve => { resolve ( notify ( ) ) ; } ) ; return this . queueTask ( task ) ; } public awaitUntilLanguageClientReady ( ) { const task = ( ) => new Promise < void > ( resolve => { resolve ( ) ; } ) ; return this . queueTask ( task ) ; } /**
     * listen for notifications from the language server.
     */ private registerNotifications ( ) { console . assert ( this . languageClient !== undefined , "This method must not be called until this.languageClient is set in \"onReady\"" ) ; this . languageClient . onNotification ( ReloadWindowNotification , ( ) => util . promptForReloadWindowDueToSettingsChange ( ) ) ; this . languageClient . onNotification ( LogTelemetryNotification , logTelemetry ) ; this . languageClient . onNotification ( ReportStatusNotification , ( e ) => this . updateStatus ( e ) ) ; this . languageClient . onNotification ( ReportTagParseStatusNotification , ( e ) => this . updateTagParseStatus ( e ) ) ; this . languageClient . onNotification ( InactiveRegionNotification , ( e ) => this . updateInactiveRegions ( e ) ) ; this . languageClient . onNotification ( CompileCommandsPathsNotification , ( e ) => this . promptCompileCommands ( e ) ) ; this . languageClient . onNotification ( ReferencesNotification , ( e ) => this . processReferencesResult ( e . referencesResult ) ) ; this . languageClient . onNotification ( ReportReferencesProgressNotification , ( e ) => this . handleReferencesProgress ( e ) ) ; this . languageClient . onNotification ( RequestCustomConfig , ( requestFile ) => { const client = < DefaultClient > clientCollection . getClientFor ( vscode . Uri . file ( requestFile ) ) ; client . handleRequestCustomConfig ( requestFile ) ; } ) ; this . languageClient . onNotification ( PublishDiagnosticsNotification , publishDiagnostics ) ; this . languageClient . onNotification ( PublishCodeAnalysisDiagnosticsNotification , publishCodeAnalysisDiagnostics ) ; this . languageClient . onNotification ( ShowMessageWindowNotification , showMessageWindow ) ; this . languageClient . onNotification ( ShowWarningNotification , showWarning ) ; this . languageClient . onNotification ( ReportTextDocumentLanguage , ( e ) => this . setTextDocumentLanguage ( e ) ) ; this . languageClient . onNotification ( SemanticTokensChanged , ( e ) => this . semanticTokensProvider ?. invalidateFile ( e ) ) ; this . languageClient . onNotification ( IntelliSenseSetupNotification , ( e ) => this . logIntellisenseSetupTime ( e ) ) ; this . languageClient . onNotification ( SetTemporaryTextDocumentLanguageNotification , ( e ) => this . setTemporaryTextDocumentLanguage ( e ) ) ; this . languageClient . onNotification ( ReportCodeAnalysisProcessedNotification , ( e ) => this . updateCodeAnalysisProcessed ( e ) ) ; this . languageClient . onNotification ( ReportCodeAnalysisTotalNotification , ( e ) => this . updateCodeAnalysisTotal ( e ) ) ; setupOutputHandlers ( ) ; } private setTextDocumentLanguage ( languageStr ) { const cppSettings = new CppSettings ( ) ; if ( cppSettings . autoAddFileAssociations ) { const is_c = languageStr . startsWith ( "c;" ) ; const is_cuda = languageStr . startsWith ( "cu;" ) ; languageStr = languageStr . substr ( is_c ? 2 : ( is_cuda ? 3 : 1 ) ) ; this . addFileAssociations ( languageStr , is_c ? "c" : ( is_cuda ? "cuda-cpp" : "cpp" ) ) ; } } private async setTemporaryTextDocumentLanguage ( params ) { const languageId = params . isC ? "c" : ( params . isCuda ? "cuda-cpp" : "cpp" ) ; const document = await vscode . workspace . openTextDocument ( params . path ) ; if ( ! ! document && document . languageId !== languageId ) { vscode . languages . setTextDocumentLanguage ( document , languageId ) ; } } private associations_for_did_change ? : Set < string > ; /**
     * listen for file created/deleted events under the ${workspaceFolder} folder
     */ private registerFileWatcher ( ) { console . assert ( this . languageClient !== undefined , "This method must not be called until this.languageClient is set in \"onReady\"" ) ; if ( this . rootFolder ) { this . rootPathFileWatcher = vscode . workspace . createFileSystemWatcher ( "**/*" , false , false , false ) ; this . rootPathFileWatcher . onDidCreate ( async ( uri ) => { if ( uri . scheme !== 'file' ) { return ; } const fileName = path . basename ( uri . fsPath ) . toLowerCase ( ) ; if ( fileName === ".editorconfig" ) { cachedEditorConfigSettings . clear ( ) ; cachedEditorConfigLookups . clear ( ) ; await this . updateActiveDocumentTextOptions ( ) ; } if ( fileName === ".clang-format" || fileName === "_clang-format" ) { cachedEditorConfigLookups . clear ( ) ; } this . languageClient . sendNotification ( FileCreatedNotification , { uri : uri . toString ( ) } ) ; } ) ; this . associations_for_did_change = new Set < string > ( [ "cu" , "cuh" , "c" , "i" , "cpp" , "cc" , "cxx" , "c++" , "cp" , "hpp" , "hh" , "hxx" , "h++" , "hp" , "h" , "ii" , "ino" , "inl" , "ipp" , "tcc" , "idl" ] ) ; const assocs = new OtherSettings ( ) . filesAssociations ; for ( const assoc in assocs ) { const dotIndex = assoc . lastIndexOf ( '.' ) ; if ( dotIndex !== - 1 ) { const ext = assoc . substr ( dotIndex + 1 ) ; this . associations_for_did_change . add ( ext ) ; } } this . rootPathFileWatcher . onDidChange ( async ( uri ) => { if ( uri . scheme !== 'file' ) { return ; } const dotIndex = uri . fsPath . lastIndexOf ( '.' ) ; const fileName = path . basename ( uri . fsPath ) . toLowerCase ( ) ; if ( fileName === ".editorconfig" ) { cachedEditorConfigSettings . clear ( ) ; cachedEditorConfigLookups . clear ( ) ; await this . updateActiveDocumentTextOptions ( ) ; } if ( dotIndex !== - 1 ) { const ext = uri . fsPath . substr ( dotIndex + 1 ) ; if ( this . associations_for_did_change ?. has ( ext ) ) { const mtime = fs . statSync ( uri . fsPath ) . mtime ; const duration = Date . now ( ) - mtime . getTime ( ) ; if ( duration < 10000 ) { this . languageClient . sendNotification ( FileChangedNotification , { uri : uri . toString ( ) } ) ; } } } } ) ; this . rootPathFileWatcher . onDidDelete ( ( uri ) => { if ( uri . scheme !== 'file' ) { return ; } const fileName = path . basename ( uri . fsPath ) . toLowerCase ( ) ; if ( fileName === ".editorconfig" ) { cachedEditorConfigSettings . clear ( ) ; cachedEditorConfigLookups . clear ( ) ; } if ( fileName === ".clang-format" || fileName === "_clang-format" ) { cachedEditorConfigLookups . clear ( ) ; } this . languageClient . sendNotification ( FileDeletedNotification , { uri : uri . toString ( ) } ) ; } ) ; this . disposables . push ( this . rootPathFileWatcher ) ; } else { this . rootPathFileWatcher = undefined ; } } /**
     * handle notifications coming from the language server
     */ public addFileAssociations ( fileAssociations , languageId ) { const settings = new OtherSettings ( ) ; const assocs = settings . filesAssociations ; const filesAndPaths = fileAssociations . split ( ";" ) ; let foundNewAssociation = false ; for ( let i = 0 ; i < filesAndPaths . length ; ++ i ) { const fileAndPath = filesAndPaths [ i ] . split ( "@" ) ; if ( fileAndPath . length === 2 ) { const file = fileAndPath [ 0 ] ; const filePath = fileAndPath [ 1 ] ; if ( ( file in assocs ) || ( ( "**/" + file ) in assocs ) ) { continue ; } const j = file . lastIndexOf ( '.' ) ; if ( j !== - 1 ) { const ext = file . substr ( j ) ; if ( ( ( "*" + ext ) in assocs ) || ( ( "**/*" + ext ) in assocs ) ) { continue ; } } let foundGlobMatch = false ; for ( const assoc in assocs ) { if ( minimatch ( filePath , assoc ) ) { foundGlobMatch = true ; break ; } } if ( foundGlobMatch ) { continue ; } assocs [ file ] = languageId ; foundNewAssociation = true ; } } if ( foundNewAssociation ) { settings . filesAssociations = assocs ; } } private updateStatus ( notificationBody ) { const message = notificationBody . status ; util . setProgress ( util . getProgressExecutableSuccess ( ) ) ; const testHook = getTestHook ( ) ; if ( message . endsWith ( "Idle" ) ) { } else if ( message . endsWith ( "Parsing" ) ) { this . model . isParsingWorkspace . Value = true ; this . model . isParsingWorkspacePausable . Value = false ; const status = { status : Status . TagParsingBegun } ; testHook . updateStatus ( status ) ; } else if ( message . endsWith ( "files" ) ) { this . model . isParsingFiles . Value = true ; } else if ( message . endsWith ( "IntelliSense" ) ) { timeStamp = Date . now ( ) ; this . model . isUpdatingIntelliSense . Value = true ; const status = { status : Status . IntelliSenseCompiling } ; testHook . updateStatus ( status ) ; } else if ( message . endsWith ( "IntelliSense done" ) ) { const settings = new CppSettings ( ) ; if ( settings . loggingLevel === "Debug" ) { const out = logger . getOutputChannelLogger ( ) ; const duration = Date . now ( ) - timeStamp ; out . appendLine ( localize ( "update.intellisense.time" , "Update IntelliSense time (sec): {0}" , duration / 1000 ) ) ; } this . model . isUpdatingIntelliSense . Value = false ; const status = { status : Status . IntelliSenseReady } ; testHook . updateStatus ( status ) ; } else if ( message . endsWith ( "Parsing done" ) ) { this . model . isParsingWorkspace . Value = false ; const status = { status : Status . TagParsingDone } ; testHook . updateStatus ( status ) ; util . setProgress ( util . getProgressParseRootSuccess ( ) ) ; } else if ( message . endsWith ( "files done" ) ) { this . model . isParsingFiles . Value = false ; } else if ( message . endsWith ( "Analysis" ) ) { this . model . isRunningCodeAnalysis . Value = true ; this . model . codeAnalysisTotal . Value = 1 ; this . model . codeAnalysisProcessed . Value = 0 ; } else if ( message . endsWith ( "Analysis done" ) ) { this . model . isRunningCodeAnalysis . Value = false ; } else if ( message . includes ( "Squiggles Finished - File name:" ) ) { const index = message . lastIndexOf ( ":" ) ; const name = message . substring ( index + 2 ) ; const status = { status : Status . IntelliSenseReady , filename : name } ; testHook . updateStatus ( status ) ; } else if ( message . endsWith ( "No Squiggles" ) ) { util . setIntelliSenseProgress ( util . getProgressIntelliSenseNoSquiggles ( ) ) ; } else if ( message . endsWith ( "Unresolved Headers" ) ) { if ( notificationBody . workspaceFolderUri ) { const client = < DefaultClient > clientCollection . getClientFor ( vscode . Uri . file ( notificationBody . workspaceFolderUri ) ) ; if ( ! client . configuration . CurrentConfiguration ?. configurationProvider ) { const showIntelliSenseFallbackMessage = new PersistentState < boolean > ( "CPP.showIntelliSenseFallbackMessage" , true ) ; if ( showIntelliSenseFallbackMessage . Value ) { ui . showConfigureIncludePathMessage ( async ( ) => { const configJSON = localize ( "configure.json.button" , "Configure (JSON)" ) ; const configUI = localize ( "configure.ui.button" , "Configure (UI)" ) ; const dontShowAgain = localize ( "dont.show.again" , "Don't Show Again" ) ; const fallbackMsg = client . configuration . VcpkgInstalled ? localize ( "update.your.intellisense.settings" , "Update your IntelliSense settings or use Vcpkg to install libraries to help find missing headers." ) : localize ( "configure.your.intellisense.settings" , "Configure your IntelliSense settings to help find missing headers." ) ; return vscode . window . showInformationMessage ( fallbackMsg , configJSON , configUI , dontShowAgain ) . then ( async ( value ) => { let commands ; switch ( value ) { case configJSON : commands = await vscode . commands . getCommands ( true ) ; if ( commands . indexOf ( "workbench.action.problems.focus" ) >= 0 ) { vscode . commands . executeCommand ( "workbench.action.problems.focus" ) ; } client . handleConfigurationEditJSONCommand ( ) ; telemetry . logLanguageServerEvent ( "SettingsCommand" , { "toast" : "json" } , undefined ) ; break ; case configUI : commands = await vscode . commands . getCommands ( true ) ; if ( commands . indexOf ( "workbench.action.problems.focus" ) >= 0 ) { vscode . commands . executeCommand ( "workbench.action.problems.focus" ) ; } client . handleConfigurationEditUICommand ( ) ; telemetry . logLanguageServerEvent ( "SettingsCommand" , { "toast" : "ui" } , undefined ) ; break ; case dontShowAgain : showIntelliSenseFallbackMessage . Value = false ; break ; } return true ; } ) ; } , ( ) => showIntelliSenseFallbackMessage . Value = false ) ; } } } } } private updateTagParseStatus ( notificationBody ) { this . model . parsingWorkspaceStatus . Value = util . getLocalizedString ( notificationBody ) ; if ( notificationBody . text . startsWith ( "Workspace parsing paused" ) ) { this . model . isParsingWorkspacePausable . Value = true ; this . model . isParsingWorkspacePaused . Value = true ; } else if ( notificationBody . text . startsWith ( "Parsing workspace" ) ) { this . model . isParsingWorkspacePausable . Value = true ; this . model . isParsingWorkspacePaused . Value = false ; } else { this . model . isParsingWorkspacePausable . Value = false ; this . model . isParsingWorkspacePaused . Value = false ; } } private updateInactiveRegions ( params ) { const settings = new CppSettings ( this . RootUri ) ; const opacity = settings . inactiveRegionOpacity ; if ( opacity !== null && opacity !== undefined ) { let backgroundColor = settings . inactiveRegionBackgroundColor ; if ( backgroundColor === "" ) { backgroundColor = undefined ; } let color = settings . inactiveRegionForegroundColor ; if ( color === "" ) { color = undefined ; } const decoration = vscode . window . createTextEditorDecorationType ( { opacity : opacity . toString ( ) , backgroundColor : backgroundColor , color : color , rangeBehavior : vscode . DecorationRangeBehavior . OpenOpen } ) ; const ranges = [ ] ; params . regions . forEach ( element => { const newRange = new vscode . Range ( element . startLine , 0 , element . endLine , 0 ) ; ranges . push ( newRange ) ; } ) ; const valuePair = this . inactiveRegionsDecorations . get ( params . uri ) ; if ( valuePair ) { valuePair . decoration . dispose ( ) ; valuePair . decoration = decoration ; valuePair . ranges = ranges ; } else { const toInsert = { decoration : decoration , ranges : ranges } ; this . inactiveRegionsDecorations . set ( params . uri , toInsert ) ; } if ( settings . dimInactiveRegions && params . fileVersion === openFileVersions . get ( params . uri ) ) { const editors = vscode . window . visibleTextEditors . filter ( e => e . document . uri . toString ( ) === params . uri ) ; for ( const e of editors ) { e . setDecorations ( decoration , ranges ) ; } } } if ( this . codeFoldingProvider ) { this . codeFoldingProvider . refresh ( ) ; } } public logIntellisenseSetupTime ( notification ) { clientCollection . timeTelemetryCollector . setSetupTime ( vscode . Uri . parse ( notification . uri ) ) ; } private promptCompileCommands ( params ) { if ( ! params . workspaceFolderUri ) { return ; } const client = < DefaultClient > clientCollection . getClientFor ( vscode . Uri . file ( params . workspaceFolderUri ) ) ; if ( client . configuration . CurrentConfiguration ?. compileCommands || client . configuration . CurrentConfiguration ?. configurationProvider ) { return ; } const rootFolder = client . RootFolder ; if ( ! rootFolder ) { return ; } const ask = new PersistentFolderState < boolean > ( "CPP.showCompileCommandsSelection" , true , rootFolder ) ; if ( ! ask . Value ) { return ; } const aCompileCommandsFile = localize ( "a.compile.commands.file" , "a compile_commands.json file" ) ; const compileCommandStr = params . paths . length > 1 ? aCompileCommandsFile : params . paths [ 0 ] ; const message = ( vscode . workspace . workspaceFolders && vscode . workspace . workspaceFolders . length > 1 ) ? localize ( "auto-configure.intellisense.folder" , "Would you like to use {0} to auto-configure IntelliSense for the '{1}' folder?" , compileCommandStr , client . Name ) : localize ( "auto-configure.intellisense.this.folder" , "Would you like to use {0} to auto-configure IntelliSense for this folder?" , compileCommandStr ) ; ui . showConfigureCompileCommandsMessage ( async ( ) => { const yes = localize ( "yes.button" , "Yes" ) ; const no = localize ( "no.button" , "No" ) ; const askLater = localize ( "ask.me.later.button" , "Ask Me Later" ) ; return vscode . window . showInformationMessage ( message , yes , no , askLater ) . then ( async ( value ) => { switch ( value ) { case yes : if ( params . paths . length > 1 ) { const index = await ui . showCompileCommands ( params . paths ) ; if ( index < 0 ) { return false ; } this . configuration . setCompileCommands ( params . paths [ index ] ) ; } else { this . configuration . setCompileCommands ( params . paths [ 0 ] ) ; } return true ; case askLater : break ; case no : ask . Value = false ; break ; } return false ; } ) ; } , ( ) => ask . Value = false ) ; } /**
     * requests to the language server
     */ public requestSwitchHeaderSource ( rootPath , fileName ) { const params = { switchHeaderSourceFileName : fileName , workspaceFolderUri : rootPath } ; return this . requestWhenReady ( ( ) => this . languageClient . sendRequest ( SwitchHeaderSourceRequest , params ) ) ; } private async updateActiveDocumentTextOptions ( ) { const editor = vscode . window . activeTextEditor ; if ( editor ?. document ?. uri . scheme === "file" && ( editor . document . languageId === "c" || editor . document . languageId === "cpp" || editor . document . languageId === "cuda-cpp" ) ) { const settings = new CppSettings ( this . RootUri ) ; if ( settings . useVcFormat ( editor . document ) ) { const editorConfigSettings = getEditorConfigSettings ( editor . document . uri . fsPath ) ; if ( editorConfigSettings . indent_style === "space" || editorConfigSettings . indent_style === "tab" ) { editor . options . insertSpaces = editorConfigSettings . indent_style === "space" ; if ( editorConfigSettings . indent_size === "tab" ) { if ( ! editorConfigSettings . tab_width !== undefined ) { editor . options . tabSize = editorConfigSettings . tab_width ; } } else if ( editorConfigSettings . indent_size !== undefined ) { editor . options . tabSize = editorConfigSettings . indent_size ; } } if ( editorConfigSettings . end_of_line !== undefined ) { editor . edit ( ( edit ) => { edit . setEndOfLine ( editorConfigSettings . end_of_line === "lf" ? vscode . EndOfLine . LF : vscode . EndOfLine . CRLF ) ; } ) ; } } } } /**
     * notifications to the language server
     */ public async activeDocumentChanged ( document ) { await this . updateActiveDocumentTextOptions ( ) ; await this . awaitUntilLanguageClientReady ( ) ; this . languageClient . sendNotification ( ActiveDocumentChangeNotification , this . languageClient . code2ProtocolConverter . asTextDocumentIdentifier ( document ) ) ; } /**
     * send notifications to the language server to restart IntelliSense for the selected file.
     */ public async restartIntelliSenseForFile ( document ) { await this . awaitUntilLanguageClientReady ( ) ; this . languageClient . sendNotification ( RestartIntelliSenseForFileNotification , this . languageClient . code2ProtocolConverter . asTextDocumentIdentifier ( document ) ) ; } /**
     * enable UI updates from this client and resume tag parsing on the server.
     */ public activate ( ) { this . model . activate ( ) ; this . resumeParsing ( ) ; } public selectionChanged ( selection ) { this . notifyWhenLanguageClientReady ( ( ) => { this . languageClient . sendNotification ( TextEditorSelectionChangeNotification , selection ) ; } ) ; } public resetDatabase ( ) { this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( ResetDatabaseNotification ) ) ; } /**
     * disable UI updates from this client and pause tag parsing on the server.
     */ public deactivate ( ) { this . model . deactivate ( ) ; } public pauseParsing ( ) { this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( PauseParsingNotification ) ) ; } public resumeParsing ( ) { this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( ResumeParsingNotification ) ) ; } public PauseCodeAnalysis ( ) { this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( PauseCodeAnalysisNotification ) ) ; this . model . isCodeAnalysisPaused . Value = true ; } public ResumeCodeAnalysis ( ) { this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( ResumeCodeAnalysisNotification ) ) ; this . model . isCodeAnalysisPaused . Value = false ; } public CancelCodeAnalysis ( ) { this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( CancelCodeAnalysisNotification ) ) ; } private updateCodeAnalysisProcessed ( processed ) { this . model . codeAnalysisProcessed . Value = processed ; } private updateCodeAnalysisTotal ( total ) { this . model . codeAnalysisTotal . Value = total ; } private doneInitialCustomBrowseConfigurationCheck : Boolean = false ; private onConfigurationsChanged ( cppProperties ) { if ( ! cppProperties . Configurations ) { return ; } const configurations = cppProperties . Configurations ; const params = { configurations : configurations , currentConfiguration : this . configuration . CurrentConfigurationIndex , workspaceFolderUri : this . RootPath , isReady : true } ; params . configurations . forEach ( ( c ) => { const compilerPathAndArgs = util . extractCompilerPathAndArgs ( c . compilerPath , c . compilerArgs ) ; c . compilerPath = compilerPathAndArgs . compilerPath ; c . compilerArgs = compilerPathAndArgs . additionalArgs ; } ) ; this . languageClient . sendNotification ( ChangeCppPropertiesNotification , params ) ; const lastCustomBrowseConfigurationProviderId = cppProperties . LastCustomBrowseConfigurationProviderId ; const lastCustomBrowseConfiguration = cppProperties . LastCustomBrowseConfiguration ; if ( ! ! lastCustomBrowseConfigurationProviderId && ! ! lastCustomBrowseConfiguration ) { if ( ! this . doneInitialCustomBrowseConfigurationCheck ) { if ( lastCustomBrowseConfiguration . Value ) { this . sendCustomBrowseConfiguration ( lastCustomBrowseConfiguration . Value , lastCustomBrowseConfigurationProviderId . Value ) ; params . isReady = false ; } this . doneInitialCustomBrowseConfigurationCheck = true ; } } const configName = configurations [ params . currentConfiguration ] . name ?? "" ; this . model . activeConfigName . setValueIfActive ( configName ) ; const newProvider = this . configuration . CurrentConfigurationProvider ; if ( ! isSameProviderExtensionId ( newProvider , this . configurationProvider ) ) { if ( this . configurationProvider ) { this . clearCustomBrowseConfiguration ( ) ; } this . configurationProvider = newProvider ; this . updateCustomBrowseConfiguration ( ) ; this . updateCustomConfigurations ( ) ; } } private onSelectedConfigurationChanged ( index ) { const params = { currentConfiguration : index , workspaceFolderUri : this . RootPath } ; this . notifyWhenLanguageClientReady ( ( ) => { this . languageClient . sendNotification ( ChangeSelectedSettingNotification , params ) ; let configName = "" ; if ( this . configuration . ConfigurationNames ) { configName = this . configuration . ConfigurationNames [ index ] ; } this . model . activeConfigName . Value = configName ; this . configuration . onDidChangeSettings ( ) ; } ) ; } private onCompileCommandsChanged ( path ) { const params = { uri : vscode . Uri . file ( path ) . toString ( ) , workspaceFolderUri : this . RootPath } ; this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( ChangeCompileCommandsNotification , params ) ) ; } private isSourceFileConfigurationItem ( input , providerVersion ) { let areOptionalsValid = false ; if ( providerVersion < Version . v5 ) { areOptionalsValid = util . isString ( input . configuration . intelliSenseMode ) && util . isString ( input . configuration . standard ) ; } else { areOptionalsValid = util . isOptionalString ( input . configuration . intelliSenseMode ) && util . isOptionalString ( input . configuration . standard ) ; } return ( input && ( util . isString ( input . uri ) || util . isUri ( input . uri ) ) && input . configuration && areOptionalsValid && util . isArrayOfString ( input . configuration . includePath ) && util . isArrayOfString ( input . configuration . defines ) && util . isOptionalArrayOfString ( input . configuration . compilerArgs ) && util . isOptionalArrayOfString ( input . configuration . forcedInclude ) ) ; } private sendCustomConfigurations ( configs , providerVersion ) { if ( ! configs || ! ( configs instanceof Array ) ) { console . warn ( "discarding invalid SourceFileConfigurationItems[]: " + configs ) ; return ; } const settings = new CppSettings ( ) ; const out = logger . getOutputChannelLogger ( ) ; if ( settings . loggingLevel === "Debug" ) { out . appendLine ( localize ( "configurations.received" , "Custom configurations received:" ) ) ; } const sanitized = [ ] ; configs . forEach ( item => { if ( this . isSourceFileConfigurationItem ( item , providerVersion ) ) { this . configurationLogging . set ( item . uri . toString ( ) , JSON . stringify ( item . configuration , null , 4 ) ) ; if ( settings . loggingLevel === "Debug" ) { out . appendLine ( `  uri: ${ item . uri . toString ( ) }` ) ; out . appendLine ( `  config: ${ JSON . stringify ( item . configuration , null , 2 ) }` ) ; } if ( item . configuration . includePath . some ( path => path . endsWith ( '**' ) ) ) { console . warn ( "custom include paths should not use recursive includes ('**')" ) ; } const itemConfig = { ... item . configuration } ; if ( util . isString ( itemConfig . compilerPath ) ) { const compilerPathAndArgs = util . extractCompilerPathAndArgs ( itemConfig . compilerPath , util . isArrayOfString ( itemConfig . compilerArgs ) ? itemConfig . compilerArgs : undefined ) ; itemConfig . compilerPath = compilerPathAndArgs . compilerPath ; itemConfig . compilerArgs = compilerPathAndArgs . additionalArgs ; } sanitized . push ( { uri : item . uri . toString ( ) , configuration : itemConfig } ) ; } else { console . warn ( "discarding invalid SourceFileConfigurationItem: " + JSON . stringify ( item ) ) ; } } ) ; if ( sanitized . length === 0 ) { return ; } const params = { configurationItems : sanitized , workspaceFolderUri : this . RootPath } ; this . languageClient . sendNotification ( CustomConfigurationNotification , params ) ; } private browseConfigurationLogging : string = "" ; private configurationLogging : Map < string , string > = new Map < string , string > ( ) ; private isWorkspaceBrowseConfiguration ( input ) { return util . isArrayOfString ( input . browsePath ) && util . isOptionalString ( input . compilerPath ) && util . isOptionalString ( input . standard ) && util . isOptionalArrayOfString ( input . compilerArgs ) && util . isOptionalString ( input . windowsSdkVersion ) ; } private sendCustomBrowseConfiguration ( config , providerId ? , timeoutOccured ? ) { const rootFolder = this . RootFolder ; if ( ! rootFolder ) { return ; } const lastCustomBrowseConfiguration = new PersistentFolderState < WorkspaceBrowseConfiguration | undefined > ( "CPP.lastCustomBrowseConfiguration" , undefined , rootFolder ) ; const lastCustomBrowseConfigurationProviderId = new PersistentFolderState < string | undefined > ( "CPP.lastCustomBrowseConfigurationProviderId" , undefined , rootFolder ) ; let sanitized ; this . browseConfigurationLogging = "" ; while ( true ) { if ( timeoutOccured || ! config || config instanceof Array ) { if ( ! timeoutOccured ) { console . log ( "Received an invalid browse configuration from configuration provider." ) ; } const configValue = lastCustomBrowseConfiguration . Value ; if ( configValue ) { sanitized = configValue ; console . log ( "Falling back to last received browse configuration: " , JSON . stringify ( sanitized , null , 2 ) ) ; break ; } console . log ( "No browse configuration is available." ) ; return ; } sanitized = { ... < WorkspaceBrowseConfiguration > config } ; if ( ! this . isWorkspaceBrowseConfiguration ( sanitized ) ) { console . log ( "Received an invalid browse configuration from configuration provider: " + JSON . stringify ( sanitized ) ) ; const configValue = lastCustomBrowseConfiguration . Value ; if ( configValue ) { sanitized = configValue ; console . log ( "Falling back to last received browse configuration: " , JSON . stringify ( sanitized , null , 2 ) ) ; break ; } return ; } const settings = new CppSettings ( ) ; if ( settings . loggingLevel === "Debug" ) { const out = logger . getOutputChannelLogger ( ) ; out . appendLine ( localize ( "browse.configuration.received" , "Custom browse configuration received: {0}" , JSON . stringify ( sanitized , null , 2 ) ) ) ; } if ( util . isString ( sanitized . compilerPath ) ) { const compilerPathAndArgs = util . extractCompilerPathAndArgs ( sanitized . compilerPath , util . isArrayOfString ( sanitized . compilerArgs ) ? sanitized . compilerArgs : undefined ) ; sanitized . compilerPath = compilerPathAndArgs . compilerPath ; sanitized . compilerArgs = compilerPathAndArgs . additionalArgs ; } lastCustomBrowseConfiguration . Value = sanitized ; if ( ! providerId ) { lastCustomBrowseConfigurationProviderId . setDefault ( ) ; } else { lastCustomBrowseConfigurationProviderId . Value = providerId ; } break ; } this . browseConfigurationLogging = `Custom browse configuration: \n${ JSON . stringify ( sanitized , null , 4 ) }\n` ; const params = { browseConfiguration : sanitized , workspaceFolderUri : this . RootPath } ; this . languageClient . sendNotification ( CustomBrowseConfigurationNotification , params ) ; } private clearCustomConfigurations ( ) { this . configurationLogging . clear ( ) ; const params = { workspaceFolderUri : this . RootPath } ; this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( ClearCustomConfigurationsNotification , params ) ) ; } private clearCustomBrowseConfiguration ( ) { this . browseConfigurationLogging = "" ; const params = { workspaceFolderUri : this . RootPath } ; this . notifyWhenLanguageClientReady ( ( ) => this . languageClient . sendNotification ( ClearCustomBrowseConfigurationNotification , params ) ) ; } /**
     * command handlers
     */ public async handleConfigurationSelectCommand ( ) { await this . awaitUntilLanguageClientReady ( ) ; const configNames = this . configuration . ConfigurationNames ; if ( configNames ) { const index = await ui . showConfigurations ( configNames ) ; if ( index < 0 ) { return ; } this . configuration . select ( index ) ; } } public async handleConfigurationProviderSelectCommand ( ) { await this . awaitUntilLanguageClientReady ( ) ; const extensionId = await ui . showConfigurationProviders ( this . configuration . CurrentConfigurationProvider ) ; if ( extensionId === undefined ) { return ; } await this . configuration . updateCustomConfigurationProvider ( extensionId ) ; if ( extensionId ) { const provider = getCustomConfigProviders ( ) . get ( extensionId ) ; this . updateCustomBrowseConfiguration ( provider ) ; this . updateCustomConfigurations ( provider ) ; telemetry . logLanguageServerEvent ( "customConfigurationProvider" , { "providerId" : extensionId } ) ; } else { this . clearCustomConfigurations ( ) ; this . clearCustomBrowseConfiguration ( ) ; } } public async handleShowParsingCommands ( ) { await this . awaitUntilLanguageClientReady ( ) ; const index = await ui . showParsingCommands ( ) ; if ( index === 0 ) { this . pauseParsing ( ) ; } else if ( index === 1 ) { this . resumeParsing ( ) ; } } public async handleShowCodeAnalysisCommands ( ) { await this . awaitUntilLanguageClientReady ( ) ; const index = await ui . showCodeAnalysisCommands ( ) ; switch ( index ) { case 0 : this . CancelCodeAnalysis ( ) ; break ; case 1 : this . PauseCodeAnalysis ( ) ; break ; case 2 : this . ResumeCodeAnalysis ( ) ; break ; } } public handleConfigurationEditCommand ( viewColumn = vscode . ViewColumn . Active ) { this . notifyWhenLanguageClientReady ( ( ) => this . configuration . handleConfigurationEditCommand ( undefined , vscode . window . showTextDocument , viewColumn ) ) ; } public handleConfigurationEditJSONCommand ( viewColumn = vscode . ViewColumn . Active ) { this . notifyWhenLanguageClientReady ( ( ) => this . configuration . handleConfigurationEditJSONCommand ( undefined , vscode . window . showTextDocument , viewColumn ) ) ; } public handleConfigurationEditUICommand ( viewColumn = vscode . ViewColumn . Active ) { this . notifyWhenLanguageClientReady ( ( ) => this . configuration . handleConfigurationEditUICommand ( undefined , vscode . window . showTextDocument , viewColumn ) ) ; } public handleAddToIncludePathCommand ( path ) { this . notifyWhenLanguageClientReady ( ( ) => this . configuration . addToIncludePathCommand ( path ) ) ; } public async handleGoToDirectiveInGroup ( next ) { const editor = vscode . window . activeTextEditor ; if ( editor ) { const params = { uri : editor . document . uri . toString ( ) , position : editor . selection . active , next : next } ; const response = await this . languageClient . sendRequest ( GoToDirectiveInGroupRequest , params ) ; if ( response ) { const p = new vscode . Position ( response . line , response . character ) ; const r = new vscode . Range ( p , p ) ; const currentEditor = vscode . window . activeTextEditor ; if ( currentEditor && editor . document . uri === currentEditor . document . uri ) { currentEditor . selection = new vscode . Selection ( r . start , r . end ) ; currentEditor . revealRange ( r ) ; } } } } public async handleCheckForCompiler ( ) { await this . awaitUntilLanguageClientReady ( ) ; const compilers = await this . getKnownCompilers ( ) ; if ( ! compilers || compilers . length === 0 ) { const compilerName = process . platform === "win32" ? "MSVC" : ( process . platform === "darwin" ? "Clang" : "GCC" ) ; vscode . window . showInformationMessage ( localize ( "no.compilers.found" , "No C++ compilers were found on your system. For your platform, we recommend installing {0} using the instructions in the editor." , compilerName ) , { modal : true } ) ; } else { const header = localize ( "compilers.found" , "We found the following C++ compilers on your system. Choose a compiler in your project's IntelliSense Configuration." ) ; let message = "" ; const settings = new CppSettings ( this . RootUri ) ; const pathSeparator = settings . preferredPathSeparator ; let isFirstLine = true ; compilers . forEach ( compiler => { if ( isFirstLine ) { isFirstLine = false ; } else { message += "\n" ; } if ( pathSeparator !== "Forward Slash" ) { message += compiler . path . replace ( /\//g , '\\' ) ; } else { message += compiler . path . replace ( /\\/g , '/' ) ; } } ) ; vscode . window . showInformationMessage ( header , { modal : true , detail : message } ) ; } } public async handleRunCodeAnalysisOnActiveFile ( ) { await this . awaitUntilLanguageClientReady ( ) ; this . languageClient . sendNotification ( CodeAnalysisNotification , CodeAnalysisScope . ActiveFile ) ; } public async handleRunCodeAnalysisOnOpenFiles ( ) { await this . awaitUntilLanguageClientReady ( ) ; this . languageClient . sendNotification ( CodeAnalysisNotification , CodeAnalysisScope . OpenFiles ) ; } public async handleRunCodeAnalysisOnAllFiles ( ) { await this . awaitUntilLanguageClientReady ( ) ; this . languageClient . sendNotification ( CodeAnalysisNotification , CodeAnalysisScope . AllFiles ) ; } public async handleClearCodeAnalysisSquiggles ( ) { await this . awaitUntilLanguageClientReady ( ) ; if ( diagnosticsCollectionCodeAnalysis ) { diagnosticsCollectionCodeAnalysis . clear ( ) ; } this . languageClient . sendNotification ( CodeAnalysisNotification , CodeAnalysisScope . ClearSquiggles ) ; } public onInterval ( ) { if ( this . innerLanguageClient !== undefined && this . configuration !== undefined ) { const params = { freeMemory : os . freemem ( ) / 1048576 } ; this . languageClient . sendNotification ( IntervalTimerNotification , params ) ; this . configuration . checkCppProperties ( ) ; this . configuration . checkCompileCommands ( ) ; } } public dispose ( ) { this . disposables . forEach ( ( d ) => d . dispose ( ) ) ; this . disposables = [ ] ; if ( this . documentFormattingProviderDisposable ) { this . documentFormattingProviderDisposable . dispose ( ) ; this . documentFormattingProviderDisposable = undefined ; } if ( this . formattingRangeProviderDisposable ) { this . formattingRangeProviderDisposable . dispose ( ) ; this . formattingRangeProviderDisposable = undefined ; } if ( this . onTypeFormattingProviderDisposable ) { this . onTypeFormattingProviderDisposable . dispose ( ) ; this . onTypeFormattingProviderDisposable = undefined ; } if ( this . codeFoldingProviderDisposable ) { this . codeFoldingProviderDisposable . dispose ( ) ; this . codeFoldingProviderDisposable = undefined ; } if ( this . semanticTokensProviderDisposable ) { this . semanticTokensProviderDisposable . dispose ( ) ; this . semanticTokensProviderDisposable = undefined ; } this . model . dispose ( ) ; } public static stopLanguageClient ( ) { return languageClient ? languageClient . stop ( ) : Promise . resolve ( ) ; } public handleReferencesIcon ( ) { this . notifyWhenLanguageClientReady ( ( ) => { const cancelling = DefaultClient . referencesPendingCancellations . length > 0 ; if ( ! cancelling ) { workspaceReferences . UpdateProgressUICounter ( this . model . referencesCommandMode . Value ) ; if ( this . ReferencesCommandMode === refs . ReferencesCommandMode . Find ) { if ( ! workspaceReferences . referencesRequestPending ) { if ( workspaceReferences . referencesRequestHasOccurred ) { if ( ! workspaceReferences . referencesRefreshPending ) { workspaceReferences . referencesRefreshPending = true ; vscode . commands . executeCommand ( "references-view.refresh" ) ; } } else { workspaceReferences . referencesRequestHasOccurred = true ; workspaceReferences . referencesRequestPending = true ; this . languageClient . sendNotification ( RequestReferencesNotification , false ) ; } } } } } ) ; } public cancelReferences ( ) { DefaultClient . referencesParams = undefined ; DefaultClient . renamePending = false ; if ( DefaultClient . referencesRequestPending || workspaceReferences . symbolSearchInProgress ) { const cancelling = DefaultClient . referencesPendingCancellations . length > 0 ; DefaultClient . referencesPendingCancellations . push ( { reject : ( ) => { } , callback : ( ) => { } } ) ; if ( ! cancelling ) { workspaceReferences . referencesCanceled = true ; languageClient . sendNotification ( CancelReferencesNotification ) ; } } } private handleReferencesProgress ( notificationBody ) { workspaceReferences . handleProgress ( notificationBody ) ; } private processReferencesResult ( referencesResult ) { workspaceReferences . processResults ( referencesResult ) ; } public setReferencesCommandMode ( mode ) { this . model . referencesCommandMode . Value = mode ; } public abortRequest ( id ) { const params = { id : id } ; languageClient . sendNotification ( AbortRequestNotification , params ) ; } } function getLanguageServerFileName ( ) { let extensionProcessName = 'cpptools' ; const plat = process . platform ; if ( plat === 'win32' ) { extensionProcessName += '.exe' ; } else if ( plat !== 'linux' && plat !== 'darwin' ) { throw "Invalid Platform" ; } return path . resolve ( util . getExtensionFilePath ( "bin" ) , extensionProcessName ) ; } class NullClient implements Client { private booleanEvent = new vscode . EventEmitter < boolean > ( ) ; private numberEvent = new vscode . EventEmitter < number > ( ) ; private stringEvent = new vscode . EventEmitter < string > ( ) ; private referencesCommandModeEvent = new vscode . EventEmitter < refs . ReferencesCommandMode > ( ) ; public get ParsingWorkspaceChanged ( ) : vscode . Event < boolean > { return this . booleanEvent . event ; } public get ParsingWorkspacePausableChanged ( ) : vscode . Event < boolean > { return this . booleanEvent . event ; } public get ParsingWorkspacePausedChanged ( ) : vscode . Event < boolean > { return this . booleanEvent . event ; } public get ParsingFilesChanged ( ) : vscode . Event < boolean > { return this . booleanEvent . event ; } public get IntelliSenseParsingChanged ( ) : vscode . Event < boolean > { return this . booleanEvent . event ; } public get RunningCodeAnalysisChanged ( ) : vscode . Event < boolean > { return this . booleanEvent . event ; } public get CodeAnalysisPausedChanged ( ) : vscode . Event < boolean > { return this . booleanEvent . event ; } public get CodeAnalysisProcessedChanged ( ) : vscode . Event < number > { return this . numberEvent . event ; } public get CodeAnalysisTotalChanged ( ) : vscode . Event < number > { return this . numberEvent . event ; } public get ReferencesCommandModeChanged ( ) : vscode . Event < refs . ReferencesCommandMode > { return this . referencesCommandModeEvent . event ; } public get TagParserStatusChanged ( ) : vscode . Event < string > { return this . stringEvent . event ; } public get ActiveConfigChanged ( ) : vscode . Event < string > { return this . stringEvent . event ; } RootPath : string = "/" ; RootRealPath : string = "/" ; RootUri ? : vscode . Uri = vscode . Uri . file ( "/" ) ; Name : string = "(empty)" ; TrackedDocuments = new Set < vscode . TextDocument > ( ) ; onDidChangeSettings ( event , isFirstClient ) { return { } ; } onDidOpenTextDocument ( document ) { } onDidCloseTextDocument ( document ) { } onDidChangeVisibleTextEditor ( editor ) { } onDidChangeTextDocument ( textDocumentChangeEvent ) { } onRegisterCustomConfigurationProvider ( provider ) { return Promise . resolve ( ) ; } updateCustomConfigurations ( requestingProvider ? ) { return Promise . resolve ( ) ; } updateCustomBrowseConfiguration ( requestingProvider ? ) { return Promise . resolve ( ) ; } provideCustomConfiguration ( docUri , requestFile ? ) { return Promise . resolve ( ) ; } logDiagnostics ( ) { return Promise . resolve ( ) ; } rescanFolder ( ) { return Promise . resolve ( ) ; } toggleReferenceResultsView ( ) { } setCurrentConfigName ( configurationName ) { return Promise . resolve ( ) ; } getCurrentConfigName ( ) { return Promise . resolve ( "" ) ; } getCurrentConfigCustomVariable ( variableName ) { return Promise . resolve ( "" ) ; } getVcpkgInstalled ( ) { return Promise . resolve ( false ) ; } getVcpkgEnabled ( ) { return Promise . resolve ( false ) ; } getCurrentCompilerPathAndArgs ( ) { return Promise . resolve ( undefined ) ; } getKnownCompilers ( ) { return Promise . resolve ( [ ] ) ; } takeOwnership ( document ) { } queueTask < T > ( task ) { return Promise . resolve ( task ( ) ) ; } requestWhenReady < T > ( request ) { return request ( ) ; } notifyWhenLanguageClientReady ( notify ) { } awaitUntilLanguageClientReady ( ) { } requestSwitchHeaderSource ( rootPath , fileName ) { return Promise . resolve ( "" ) ; } activeDocumentChanged ( document ) { return Promise . resolve ( ) ; } restartIntelliSenseForFile ( document ) { return Promise . resolve ( ) ; } activate ( ) { } selectionChanged ( selection ) { } resetDatabase ( ) { } deactivate ( ) { } pauseParsing ( ) { } resumeParsing ( ) { } PauseCodeAnalysis ( ) { } ResumeCodeAnalysis ( ) { } CancelCodeAnalysis ( ) { } handleConfigurationSelectCommand ( ) { return Promise . resolve ( ) ; } handleConfigurationProviderSelectCommand ( ) { return Promise . resolve ( ) ; } handleShowParsingCommands ( ) { return Promise . resolve ( ) ; } handleShowCodeAnalysisCommands ( ) { return Promise . resolve ( ) ; } handleReferencesIcon ( ) { } handleConfigurationEditCommand ( viewColumn ? ) { } handleConfigurationEditJSONCommand ( viewColumn ? ) { } handleConfigurationEditUICommand ( viewColumn ? ) { } handleAddToIncludePathCommand ( path ) { } handleGoToDirectiveInGroup ( next ) { return Promise . resolve ( ) ; } handleCheckForCompiler ( ) { return Promise . resolve ( ) ; } handleRunCodeAnalysisOnActiveFile ( ) { return Promise . resolve ( ) ; } handleRunCodeAnalysisOnOpenFiles ( ) { return Promise . resolve ( ) ; } handleRunCodeAnalysisOnAllFiles ( ) { return Promise . resolve ( ) ; } handleClearCodeAnalysisSquiggles ( ) { return Promise . resolve ( ) ; } onInterval ( ) { } dispose ( ) { this . booleanEvent . dispose ( ) ; this . stringEvent . dispose ( ) ; } addFileAssociations ( fileAssociations , languageId ) { } sendDidChangeSettings ( settings ) { } }