diff --git a/src/cpptools.ts b/src/cpptools.ts index 4f33c4638..d3d55df60 100644 --- a/src/cpptools.ts +++ b/src/cpptools.ts @@ -28,12 +28,15 @@ type StandardVersion = "c89" | "c99" | "c11" | "c17" | "c++98" | "c++03" | "c++1 export interface DiagnosticsCpptools { isReady: boolean; hasCodeModel: boolean; + activeBuildType: string; + buildTypesSeen: string[]; targetCount: number; executablesCount: number; librariesCount: number; targets: DiagnosticsTarget[]; requests: string[]; responses: cpt.SourceFileConfigurationItem[]; + partialMatches: DiagnosticsPartialMatch[]; } export interface DiagnosticsTarget { @@ -41,6 +44,11 @@ export interface DiagnosticsTarget { type: TargetTypeString; } +export interface DiagnosticsPartialMatch { + request: string; + matches: string | string[]; +} + export interface CompileFlagInformation { extraDefinitions: string[]; standard?: StandardVersion; @@ -407,6 +415,9 @@ export class CppConfigurationProvider implements cpt.CustomConfigurationProvider */ private _activeTarget: string|null = null; + private activeBuildType: string|null = null; + private buildTypesSeen = new Set(); + /** * Create a source file configuration for the given file group. * @param fileGroup The file group from the code model to create config data for @@ -431,11 +442,6 @@ export class CppConfigurationProvider implements cpt.CustomConfigurationProvider throw new MissingCompilerException(); } - const buildType = opts.cache.get('CMAKE_BUILD_TYPE'); - if (buildType) { - opts.activeBuildTypeVariant = buildType.as(); - } - const targetFromToolchains = comp_toolchains?.target; const targetArchFromToolchains = targetFromToolchains ? parseTargetArch(targetFromToolchains) : undefined; @@ -536,11 +542,23 @@ export class CppConfigurationProvider implements cpt.CustomConfigurationProvider // Reset the counters for diagnostics this.requests.clear(); this.responses.clear(); + this.buildTypesSeen.clear(); this.targets = []; let hadMissingCompilers = false; this._workspaceBrowseConfiguration = {browsePath: []}; this._activeTarget = opts.activeTarget; + this.activeBuildType = opts.activeBuildTypeVariant; + for (const config of opts.codeModelContent.configurations) { + this.buildTypesSeen.add(config.name); + } + if (this.buildTypesSeen.size > 0 && !this.buildTypesSeen.has(opts.activeBuildTypeVariant || "")) { + const configName = opts.codeModelContent.configurations[0].name; + log.warning(localize('build.type.out.of.sync', + "The build configurations generated do not contain the active build configuration. Using '{0}' for CMAKE_BUILD_TYPE instead of '{1}' to ensure that IntelliSense configurations can be found", + configName, opts.activeBuildTypeVariant)); + opts.activeBuildTypeVariant = configName; + } for (const config of opts.codeModelContent.configurations) { // Update only the active build type variant. if (config.name === opts.activeBuildTypeVariant) { @@ -596,11 +614,34 @@ export class CppConfigurationProvider implements cpt.CustomConfigurationProvider } getDiagnostics(): DiagnosticsCpptools { + const partialMatches: DiagnosticsPartialMatch[] = []; + for (const request of this.requests) { + const uri = vscode.Uri.parse(request); + const configuration = this._getConfiguration(uri); + if (!configuration) { + const fileName = path.basename(uri.fsPath); + const matches = []; + for (const [key, _] of this._fileIndex) { + if (path.basename(key) === fileName) { + matches.push(key); + } + } + if (matches.length === 1) { + partialMatches.push({ request, matches: matches.toString() }); + } else if (matches.length > 1) { + partialMatches.push({request, matches}); + } + } + } + return { isReady: this.ready, hasCodeModel: this._fileIndex.size > 0, + activeBuildType: this.activeBuildType || "", + buildTypesSeen: [...this.buildTypesSeen.values()], requests: [...this.requests.values() ], responses: [...this.responses.values()], + partialMatches, targetCount: this.targets.length, executablesCount: this.targets.reduce((acc, target) => target.type === 'EXECUTABLE' ? acc + 1 : acc, 0), librariesCount: this.targets.reduce((acc, target) => target.type.endsWith('LIBRARY') ? acc + 1 : acc, 0), diff --git a/src/extension.ts b/src/extension.ts index 68f13c6b8..c1f83e56b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -743,7 +743,19 @@ class ExtensionManager implements vscode.Disposable { if (drv) { drv.isMultiConfig = isMultiConfig; } - const actualBuildType = isMultiConfig && cmt.useCMakePresets ? cmt.buildPreset?.configuration || null : cmt.activeVariant; + const actualBuildType = (() => { + if (cmt.useCMakePresets) { + if (isMultiConfig) { + return cmt.buildPreset?.configuration || null; + } else { + const buildType = cache.get('CMAKE_BUILD_TYPE'); + return buildType ? buildType.as() : null; // Single config generators set the build type during config, not build. + } + } else { + return cmt.activeVariant; + } + })(); + const clCompilerPath = await findCLCompilerPath(env); this._configProvider.cpptoolsVersion = cpptools.getVersion(); let codeModelContent;