From fa4c5d16b39341e78b3bad6f8c340a1289ecad29 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Tue, 15 Jan 2019 10:47:36 -0800 Subject: [PATCH 01/38] Generate a C/C++ build task --- Extension/src/LanguageServer/extension.ts | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index be344106d..e5d967129 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -36,6 +36,8 @@ let tempCommands: vscode.Disposable[] = []; let activatedPreviously: PersistentWorkspaceState; const insiderUpdateTimerInterval: number = 1000 * 60 * 60; +let taskProvider: vscode.Disposable; + /** * activate: set up the extension for language services */ @@ -54,7 +56,7 @@ export function activate(activationEventOccurred: boolean): void { tempCommands.push(vscode.workspace.onDidOpenTextDocument(d => onDidOpenTextDocument(d))); // Check if an activation event has already occurred. - if (activationEventOccurred) { + if (activationEventOccurred) { onActivationEvent(); return; } @@ -70,6 +72,19 @@ export function activate(activationEventOccurred: boolean): void { } } + let buildPromise: Thenable | undefined = undefined; + taskProvider = vscode.tasks.registerTaskProvider('shell', { + provideTasks: () => { + if (!buildPromise) { + buildPromise = getBuildTasks(); + } + return buildPromise; + }, + resolveTask(task: vscode.Task): vscode.Task { + return undefined; + } + }); + // handle "onLanguage:cpp" and "onLanguage:c" activation events. if (vscode.workspace.textDocuments !== undefined && vscode.workspace.textDocuments.length > 0) { for (let i: number = 0; i < vscode.workspace.textDocuments.length; ++i) { @@ -82,6 +97,30 @@ export function activate(activationEventOccurred: boolean): void { } } +async function getBuildTasks(): Promise { + + let compiler: string; + if (true /*g++ detected*/) { + compiler = 'gcc'; + } + + const kind: vscode.TaskDefinition = { + type: 'shell', + label: 'build', + command: compiler, + }; + + let command: vscode.ShellExecution = new vscode.ShellExecution(compiler, ['-g', 'main.cpp', '-o', 'main']); + let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), 'build', 'C/C++', command, '$gcc'); + task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning + task.group = vscode.TaskGroup.Build; + + let result: vscode.Task[] = []; + result.push(task); + + return result; +} + function onDidOpenTextDocument(document: vscode.TextDocument): void { if (document.languageId === "c" || document.languageId === "cpp") { onActivationEvent(); @@ -717,6 +756,9 @@ export function deactivate(): Thenable { disposables.forEach(d => d.dispose()); languageConfigurations.forEach(d => d.dispose()); ui.dispose(); + if (taskProvider) { + taskProvider.dispose(); + } return clients.dispose(); } From bf31fe64559f8f3f17311bf63f9ae8f77c8114d2 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Tue, 15 Jan 2019 10:48:16 -0800 Subject: [PATCH 02/38] Cleaning --- Extension/src/LanguageServer/extension.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index e5d967129..af750f7c4 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -98,23 +98,22 @@ export function activate(activationEventOccurred: boolean): void { } async function getBuildTasks(): Promise { - let compiler: string; if (true /*g++ detected*/) { compiler = 'gcc'; } - + const kind: vscode.TaskDefinition = { type: 'shell', label: 'build', command: compiler, }; - - let command: vscode.ShellExecution = new vscode.ShellExecution(compiler, ['-g', 'main.cpp', '-o', 'main']); + + const command: vscode.ShellExecution = new vscode.ShellExecution(compiler, ['-g', 'main.cpp', '-o', 'main']); let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), 'build', 'C/C++', command, '$gcc'); task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning task.group = vscode.TaskGroup.Build; - + let result: vscode.Task[] = []; result.push(task); From a5d3354d8fde1791e1d31f7edc03bfb99a5b1225 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Tue, 15 Jan 2019 16:16:58 -0800 Subject: [PATCH 03/38] Move args into definition --- Extension/src/LanguageServer/extension.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index af750f7c4..94ada0214 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -107,9 +107,10 @@ async function getBuildTasks(): Promise { type: 'shell', label: 'build', command: compiler, + args: ['-g', '${fileBasename}', '-o', '${fileBasenameNoExtension}'] }; - const command: vscode.ShellExecution = new vscode.ShellExecution(compiler, ['-g', 'main.cpp', '-o', 'main']); + const command: vscode.ShellExecution = new vscode.ShellExecution(compiler); let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), 'build', 'C/C++', command, '$gcc'); task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning task.group = vscode.TaskGroup.Build; From 02af719b2b8aceb8f38c9333629dc4a439260ea5 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Tue, 15 Jan 2019 16:41:24 -0800 Subject: [PATCH 04/38] Add args to shellexecution to allow calling the task without first configuring; Add TODO's --- Extension/src/LanguageServer/extension.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 94ada0214..f94b4fc2f 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -99,19 +99,27 @@ export function activate(activationEventOccurred: boolean): void { async function getBuildTasks(): Promise { let compiler: string; + + // TODO Find compiler. If only one compiler is found, only generate one task w/ the found compiler + // If more than one compiler is found, create multiple tasks w/ each compiler if (true /*g++ detected*/) { - compiler = 'gcc'; + compiler = 'g++'; // TODO get full compiler path? In case the compiler is not in $PATH + } else { + // TODO no compiler found. Show a dialog message prompting the user to install a compiler } + const taskName: string = "build active file"; + // TODO consider adding -std=c++1z or equivalent for other compilers + const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/${fileBasenameNoExtension}']; const kind: vscode.TaskDefinition = { type: 'shell', - label: 'build', + label: taskName, command: compiler, - args: ['-g', '${fileBasename}', '-o', '${fileBasenameNoExtension}'] + args: args, }; - const command: vscode.ShellExecution = new vscode.ShellExecution(compiler); - let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), 'build', 'C/C++', command, '$gcc'); + const command: vscode.ShellExecution = new vscode.ShellExecution(compiler, args); + let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), taskName, 'C/C++', command, '$gcc'); task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning task.group = vscode.TaskGroup.Build; From 20a0520f53dca7af3356ddfe2b44cc7369f723c3 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Tue, 22 Jan 2019 13:59:13 -0800 Subject: [PATCH 05/38] Read compiler paths sent in defaults to generate task list --- Extension/src/LanguageServer/client.ts | 6 ++ .../src/LanguageServer/configurations.ts | 8 +++ Extension/src/LanguageServer/extension.ts | 62 +++++++++++-------- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 1b0dbd1c7..f10cae0eb 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -201,6 +201,7 @@ export interface Client { updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable; provideCustomConfiguration(document: vscode.TextDocument): Promise; getCurrentConfigName(): Thenable; + getCompilerPaths(): Thenable; takeOwnership(document: vscode.TextDocument): void; queueTask(task: () => Thenable): Thenable; requestWhenReady(request: () => Thenable): Thenable; @@ -656,6 +657,10 @@ class DefaultClient implements Client { return this.queueTask(() => Promise.resolve(this.configuration.CurrentConfiguration.name)); } + public getCompilerPaths(): Thenable { + return this.queueTask(() => Promise.resolve(this.configuration.CompilerPaths)); + } + /** * Take ownership of a document that was previously serviced by another client. * This process involves sending a textDocument/didOpen message to the server so @@ -1344,6 +1349,7 @@ class NullClient implements Client { updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable { return Promise.resolve(); } provideCustomConfiguration(document: vscode.TextDocument): Promise { return Promise.resolve(); } getCurrentConfigName(): Thenable { return Promise.resolve(""); } + getCompilerPaths(): Thenable { return Promise.resolve([]); } takeOwnership(document: vscode.TextDocument): void {} queueTask(task: () => Thenable): Thenable { return task(); } requestWhenReady(request: () => Thenable): Thenable { return; } diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 69ffbc4bb..361f08f59 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -46,6 +46,7 @@ export interface ConfigurationJson { export interface Configuration { name: string; compilerPath?: string; + compilerPaths?: string[]; cStandard?: string; cppStandard?: string; includePath?: string[]; @@ -67,6 +68,7 @@ export interface Browse { export interface CompilerDefaults { compilerPath: string; + compilerPaths: string[]; cStandard: string; cppStandard: string; includes: string[]; @@ -85,6 +87,7 @@ export class CppProperties { private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails. private compileCommandFileWatchers: fs.FSWatcher[] = []; private defaultCompilerPath: string = null; + private compilerPaths: string[] = null; private defaultCStandard: string = null; private defaultCppStandard: string = null; private defaultIncludes: string[] = null; @@ -147,6 +150,7 @@ export class CppProperties { public get Configurations(): Configuration[] { return this.configurationJson.configurations; } public get CurrentConfigurationIndex(): number { return this.currentConfigurationIndex.Value; } public get CurrentConfiguration(): Configuration { return this.Configurations[this.CurrentConfigurationIndex]; } + public get CompilerPaths(): string[] { return this.compilerPaths; } public get CurrentConfigurationProvider(): string|null { if (this.CurrentConfiguration.configurationProvider) { @@ -163,6 +167,7 @@ export class CppProperties { public set CompilerDefaults(compilerDefaults: CompilerDefaults) { this.defaultCompilerPath = compilerDefaults.compilerPath; + this.compilerPaths = compilerDefaults.compilerPaths; this.defaultCStandard = compilerDefaults.cStandard; this.defaultCppStandard = compilerDefaults.cppStandard; this.defaultIncludes = compilerDefaults.includes; @@ -245,6 +250,9 @@ export class CppProperties { if (isUnset(settings.defaultCompilerPath) && this.defaultCompilerPath) { configuration.compilerPath = this.defaultCompilerPath; } + if (this.compilerPaths) { + configuration.compilerPaths = this.compilerPaths; + } if (isUnset(settings.defaultCStandard) && this.defaultCStandard) { configuration.cStandard = this.defaultCStandard; } diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index f94b4fc2f..700a255b9 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -22,6 +22,7 @@ import { Range } from 'vscode-languageclient'; import { ChildProcess, spawn, execSync } from 'child_process'; import * as tmp from 'tmp'; import { getTargetBuildInfo } from '../githubAPI'; +import * as configs from './configurations'; let prevCrashFile: string; let clients: ClientCollection; @@ -61,17 +62,6 @@ export function activate(activationEventOccurred: boolean): void { return; } - // handle "workspaceContains:/.vscode/c_cpp_properties.json" activation event. - if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { - for (let i: number = 0; i < vscode.workspace.workspaceFolders.length; ++i) { - let config: string = path.join(vscode.workspace.workspaceFolders[i].uri.fsPath, ".vscode/c_cpp_properties.json"); - if (fs.existsSync(config)) { - onActivationEvent(); - return; - } - } - } - let buildPromise: Thenable | undefined = undefined; taskProvider = vscode.tasks.registerTaskProvider('shell', { provideTasks: () => { @@ -85,6 +75,17 @@ export function activate(activationEventOccurred: boolean): void { } }); + // handle "workspaceContains:/.vscode/c_cpp_properties.json" activation event. + if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { + for (let i: number = 0; i < vscode.workspace.workspaceFolders.length; ++i) { + let config: string = path.join(vscode.workspace.workspaceFolders[i].uri.fsPath, ".vscode/c_cpp_properties.json"); + if (fs.existsSync(config)) { + onActivationEvent(); + return; + } + } + } + // handle "onLanguage:cpp" and "onLanguage:c" activation events. if (vscode.workspace.textDocuments !== undefined && vscode.workspace.textDocuments.length > 0) { for (let i: number = 0; i < vscode.workspace.textDocuments.length; ++i) { @@ -108,23 +109,30 @@ async function getBuildTasks(): Promise { // TODO no compiler found. Show a dialog message prompting the user to install a compiler } - const taskName: string = "build active file"; - // TODO consider adding -std=c++1z or equivalent for other compilers - const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/${fileBasenameNoExtension}']; - const kind: vscode.TaskDefinition = { - type: 'shell', - label: taskName, - command: compiler, - args: args, - }; - - const command: vscode.ShellExecution = new vscode.ShellExecution(compiler, args); - let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), taskName, 'C/C++', command, '$gcc'); - task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning - task.group = vscode.TaskGroup.Build; - + let activeClient: Client = getActiveClient(); let result: vscode.Task[] = []; - result.push(task); + let compilerPaths: string[] = await activeClient.getCurrentConfigCompilerPaths(); + compilerPaths.forEach(compilerPath => { + let compilerName: string = path.basename(compilerPath); + const taskName: string = compilerName + " build active file"; + + // TODO consider adding -std=c++1z or equivalent for other compilers + const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/${fileBasenameNoExtension}']; + + const kind: vscode.TaskDefinition = { + type: 'shell', + label: taskName, + command: compilerPath, + args: args, + }; + + const command: vscode.ShellExecution = new vscode.ShellExecution(compiler, args); + let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), taskName, 'C/Cpp', command, '$gcc'); + task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning + task.group = vscode.TaskGroup.Build; + + result.push(task); + }); return result; } From d81ba1ecf661de09fb0bd9b3694db0655bab74a7 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Thu, 24 Jan 2019 10:18:51 -0800 Subject: [PATCH 06/38] Rename compilerPaths to compilerInfo; Filter tasks based on file extension --- Extension/src/LanguageServer/client.ts | 8 ++-- .../src/LanguageServer/configurations.ts | 26 ++++++++--- Extension/src/LanguageServer/extension.ts | 43 ++++++++++--------- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index f10cae0eb..150c86c07 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -201,7 +201,7 @@ export interface Client { updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable; provideCustomConfiguration(document: vscode.TextDocument): Promise; getCurrentConfigName(): Thenable; - getCompilerPaths(): Thenable; + getCompilerInfo(): Thenable; takeOwnership(document: vscode.TextDocument): void; queueTask(task: () => Thenable): Thenable; requestWhenReady(request: () => Thenable): Thenable; @@ -657,8 +657,8 @@ class DefaultClient implements Client { return this.queueTask(() => Promise.resolve(this.configuration.CurrentConfiguration.name)); } - public getCompilerPaths(): Thenable { - return this.queueTask(() => Promise.resolve(this.configuration.CompilerPaths)); + public getCompilerInfo(): Thenable { + return this.queueTask(() => Promise.resolve(this.configuration.CompilerInfo)); } /** @@ -1349,7 +1349,7 @@ class NullClient implements Client { updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable { return Promise.resolve(); } provideCustomConfiguration(document: vscode.TextDocument): Promise { return Promise.resolve(); } getCurrentConfigName(): Thenable { return Promise.resolve(""); } - getCompilerPaths(): Thenable { return Promise.resolve([]); } + getCompilerInfo(): Thenable { return Promise.resolve([]); } takeOwnership(document: vscode.TextDocument): void {} queueTask(task: () => Thenable): Thenable { return task(); } requestWhenReady(request: () => Thenable): Thenable { return; } diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 361f08f59..dcbf49dfe 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -46,7 +46,7 @@ export interface ConfigurationJson { export interface Configuration { name: string; compilerPath?: string; - compilerPaths?: string[]; + compilerInfo?: CompilerInfo[]; cStandard?: string; cppStandard?: string; includePath?: string[]; @@ -66,9 +66,21 @@ export interface Browse { databaseFilename?: string; } +export namespace CompilerInfo { + export enum language_association { + c, + cpp + } +} + +export interface CompilerInfo { + path: string; + languageAssociation: string; +} + export interface CompilerDefaults { compilerPath: string; - compilerPaths: string[]; + compilerInfo: CompilerInfo[]; cStandard: string; cppStandard: string; includes: string[]; @@ -87,7 +99,7 @@ export class CppProperties { private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails. private compileCommandFileWatchers: fs.FSWatcher[] = []; private defaultCompilerPath: string = null; - private compilerPaths: string[] = null; + private compilerInfo: CompilerInfo[] = null; private defaultCStandard: string = null; private defaultCppStandard: string = null; private defaultIncludes: string[] = null; @@ -150,7 +162,7 @@ export class CppProperties { public get Configurations(): Configuration[] { return this.configurationJson.configurations; } public get CurrentConfigurationIndex(): number { return this.currentConfigurationIndex.Value; } public get CurrentConfiguration(): Configuration { return this.Configurations[this.CurrentConfigurationIndex]; } - public get CompilerPaths(): string[] { return this.compilerPaths; } + public get CompilerInfo(): CompilerInfo[] { return this.compilerInfo; } public get CurrentConfigurationProvider(): string|null { if (this.CurrentConfiguration.configurationProvider) { @@ -167,7 +179,7 @@ export class CppProperties { public set CompilerDefaults(compilerDefaults: CompilerDefaults) { this.defaultCompilerPath = compilerDefaults.compilerPath; - this.compilerPaths = compilerDefaults.compilerPaths; + this.compilerInfo = compilerDefaults.compilerInfo; this.defaultCStandard = compilerDefaults.cStandard; this.defaultCppStandard = compilerDefaults.cppStandard; this.defaultIncludes = compilerDefaults.includes; @@ -250,8 +262,8 @@ export class CppProperties { if (isUnset(settings.defaultCompilerPath) && this.defaultCompilerPath) { configuration.compilerPath = this.defaultCompilerPath; } - if (this.compilerPaths) { - configuration.compilerPaths = this.compilerPaths; + if (this.compilerInfo) { + configuration.compilerInfo = this.compilerInfo; } if (isUnset(settings.defaultCStandard) && this.defaultCStandard) { configuration.cStandard = this.defaultCStandard; diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 700a255b9..d1c86dd5e 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -62,13 +62,10 @@ export function activate(activationEventOccurred: boolean): void { return; } - let buildPromise: Thenable | undefined = undefined; + // let buildPromise: Thenable | undefined = undefined; taskProvider = vscode.tasks.registerTaskProvider('shell', { provideTasks: () => { - if (!buildPromise) { - buildPromise = getBuildTasks(); - } - return buildPromise; + return getBuildTasks(); }, resolveTask(task: vscode.Task): vscode.Task { return undefined; @@ -99,34 +96,38 @@ export function activate(activationEventOccurred: boolean): void { } async function getBuildTasks(): Promise { - let compiler: string; + const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor; + if (!activeEditor) { + return; + } - // TODO Find compiler. If only one compiler is found, only generate one task w/ the found compiler - // If more than one compiler is found, create multiple tasks w/ each compiler - if (true /*g++ detected*/) { - compiler = 'g++'; // TODO get full compiler path? In case the compiler is not in $PATH - } else { - // TODO no compiler found. Show a dialog message prompting the user to install a compiler + // Do not show build tasks for header files + const activeFileExt: string = path.extname(activeEditor.document.fileName); + const headerExt: string[] = [".hpp", ".hh", ".hxx", ".h"]; + if (!headerExt.every(ext => { return activeFileExt !== ext; })) { + return; } - let activeClient: Client = getActiveClient(); + const activeClient: Client = getActiveClient(); let result: vscode.Task[] = []; - let compilerPaths: string[] = await activeClient.getCurrentConfigCompilerPaths(); - compilerPaths.forEach(compilerPath => { - let compilerName: string = path.basename(compilerPath); - const taskName: string = compilerName + " build active file"; + const compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); - // TODO consider adding -std=c++1z or equivalent for other compilers - const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/${fileBasenameNoExtension}']; + compilerInfo.forEach(compilerInfo => { + // Only show C++ compilers for C++ files; C compilers for C files + if (compilerInfo.languageAssociation !== activeEditor.document.languageId) { + return; + } + const taskName: string = path.basename(compilerInfo.path) + " build active file"; + const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/${fileBasenameNoExtension}']; const kind: vscode.TaskDefinition = { type: 'shell', label: taskName, - command: compilerPath, + command: compilerInfo, args: args, }; - const command: vscode.ShellExecution = new vscode.ShellExecution(compiler, args); + const command: vscode.ShellExecution = new vscode.ShellExecution(compilerInfo.path, args); let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), taskName, 'C/Cpp', command, '$gcc'); task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning task.group = vscode.TaskGroup.Build; From 31d5fc36fc8dca0a96979e35847ea6a2b97ea2d0 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Fri, 25 Jan 2019 10:58:54 -0800 Subject: [PATCH 07/38] Use our own file extension filters to decide whether tasks are presented --- Extension/src/LanguageServer/extension.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index d1c86dd5e..f9594738f 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -95,6 +95,9 @@ export function activate(activationEventOccurred: boolean): void { } } +/** + * Generate tasks to build the current file based on the user's detected compilers and the current file's extension + */ async function getBuildTasks(): Promise { const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor; if (!activeEditor) { @@ -108,13 +111,22 @@ async function getBuildTasks(): Promise { return; } + // Don't offer tasks if the active file's extension is not a recognized C/C++ extension + let cppExtensions: string[] = [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".mm", ".ino", ".inl"]; + const activeFileIsCpp: boolean = cppExtensions.find(ext => ext === activeFileExt) !== undefined; + const activeFileIsC: boolean = activeFileExt === '.c'; + if (!activeFileIsCpp && activeFileExt !== '.c') { + return; + } + const activeClient: Client = getActiveClient(); let result: vscode.Task[] = []; const compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); compilerInfo.forEach(compilerInfo => { // Only show C++ compilers for C++ files; C compilers for C files - if (compilerInfo.languageAssociation !== activeEditor.document.languageId) { + if ((compilerInfo.languageAssociation === 'cpp' && !activeFileIsCpp) || + (compilerInfo.languageAssociation === 'c' && !activeFileIsC)) { return; } @@ -123,12 +135,13 @@ async function getBuildTasks(): Promise { const kind: vscode.TaskDefinition = { type: 'shell', label: taskName, - command: compilerInfo, + command: compilerInfo.path, args: args, }; const command: vscode.ShellExecution = new vscode.ShellExecution(compilerInfo.path, args); - let task: vscode.Task = new vscode.Task(kind, vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri), taskName, 'C/Cpp', command, '$gcc'); + const target: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri); + let task: vscode.Task = new vscode.Task(kind, target, taskName, 'C/Cpp', command, '$gcc'); task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning task.group = vscode.TaskGroup.Build; From e807b54672232fa60b2eb2d1657054e9fa5a020a Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Fri, 25 Jan 2019 11:10:01 -0800 Subject: [PATCH 08/38] Show dialog when no compilers are found --- Extension/src/LanguageServer/extension.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index f9594738f..54bf57896 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -122,6 +122,17 @@ async function getBuildTasks(): Promise { const activeClient: Client = getActiveClient(); let result: vscode.Task[] = []; const compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); + if (!compilerInfo) { + const dontShowAgain: string = "Don't Show Again"; + const learnMore: string = "Learn More"; + const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/Cpp: build active file tasks."; + vscode.window.showInformationMessage(message, learnMore, dontShowAgain).then(selection => { + if (selection === learnMore) { + console.log("foo"); + } + }); + return; + } compilerInfo.forEach(compilerInfo => { // Only show C++ compilers for C++ files; C compilers for C files From 5eede83ea191ac5c72c2d1a4e57b7c709dc165a7 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Fri, 25 Jan 2019 14:35:39 -0800 Subject: [PATCH 09/38] Display a message if no compilers are found --- Extension/src/LanguageServer/extension.ts | 27 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 54bf57896..ccb607a50 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -14,7 +14,7 @@ import { UI, getUI } from './ui'; import { Client } from './client'; import { ClientCollection } from './clientCollection'; import { CppSettings } from './settings'; -import { PersistentWorkspaceState } from './persistentState'; +import { PersistentState, PersistentWorkspaceState } from './persistentState'; import { getLanguageConfig } from './languageConfig'; import { getCustomConfigProviders } from './customProviders'; import { PlatformInformation } from '../platform'; @@ -121,16 +121,31 @@ async function getBuildTasks(): Promise { const activeClient: Client = getActiveClient(); let result: vscode.Task[] = []; + + // Get the found compilers via the whitelisted locations sent over from C++ side, displaying a message if none are found const compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); if (!compilerInfo) { const dontShowAgain: string = "Don't Show Again"; const learnMore: string = "Learn More"; const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/Cpp: build active file tasks."; - vscode.window.showInformationMessage(message, learnMore, dontShowAgain).then(selection => { - if (selection === learnMore) { - console.log("foo"); - } - }); + + let showNoCompilerFoundMessage: PersistentState = new PersistentState("CPP.showNoCompilerFoundMessage", true); + if (showNoCompilerFoundMessage) { + vscode.window.showInformationMessage(message, learnMore, dontShowAgain).then(selection => { + switch (selection) { + case learnMore: + const uri: vscode.Uri = vscode.Uri.parse(`https://go.microsoft.com/fwlink/?linkid=864631`); + vscode.commands.executeCommand('vscode.open', uri); + break; + case dontShowAgain: + showNoCompilerFoundMessage.Value = false; + break; + default: + break; + } + return true; + }); + } return; } From 8a9580108a9272ab0ff7889eaadd1768643fa03f Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Mon, 28 Jan 2019 13:49:11 -0800 Subject: [PATCH 10/38] Add compilerPath getter to config; Use it to offer another task --- Extension/src/LanguageServer/client.ts | 6 +++ .../src/LanguageServer/configurations.ts | 1 + Extension/src/LanguageServer/extension.ts | 41 +++++++++++-------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 150c86c07..102ce3d46 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -201,6 +201,7 @@ export interface Client { updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable; provideCustomConfiguration(document: vscode.TextDocument): Promise; getCurrentConfigName(): Thenable; + getCompilerPath(): Thenable; getCompilerInfo(): Thenable; takeOwnership(document: vscode.TextDocument): void; queueTask(task: () => Thenable): Thenable; @@ -657,6 +658,10 @@ class DefaultClient implements Client { return this.queueTask(() => Promise.resolve(this.configuration.CurrentConfiguration.name)); } + public getCompilerPath(): Thenable { + return this.queueTask(() => Promise.resolve(this.configuration.CompilerPath)); + } + public getCompilerInfo(): Thenable { return this.queueTask(() => Promise.resolve(this.configuration.CompilerInfo)); } @@ -1349,6 +1354,7 @@ class NullClient implements Client { updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable { return Promise.resolve(); } provideCustomConfiguration(document: vscode.TextDocument): Promise { return Promise.resolve(); } getCurrentConfigName(): Thenable { return Promise.resolve(""); } + getCompilerPath(): Thenable { return Promise.resolve(""); } getCompilerInfo(): Thenable { return Promise.resolve([]); } takeOwnership(document: vscode.TextDocument): void {} queueTask(task: () => Thenable): Thenable { return task(); } diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index dcbf49dfe..2fa48e593 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -162,6 +162,7 @@ export class CppProperties { public get Configurations(): Configuration[] { return this.configurationJson.configurations; } public get CurrentConfigurationIndex(): number { return this.currentConfigurationIndex.Value; } public get CurrentConfiguration(): Configuration { return this.Configurations[this.CurrentConfigurationIndex]; } + public get CompilerPath(): string { return this.CurrentConfiguration.compilerPath; } public get CompilerInfo(): CompilerInfo[] { return this.compilerInfo; } public get CurrentConfigurationProvider(): string|null { diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index ccb607a50..96bb61e26 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -96,7 +96,7 @@ export function activate(activationEventOccurred: boolean): void { } /** - * Generate tasks to build the current file based on the user's detected compilers and the current file's extension + * Generate tasks to build the current file based on the user's detected compilers, the user's set compiler path, and the current file's extension */ async function getBuildTasks(): Promise { const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor; @@ -106,8 +106,8 @@ async function getBuildTasks(): Promise { // Do not show build tasks for header files const activeFileExt: string = path.extname(activeEditor.document.fileName); - const headerExt: string[] = [".hpp", ".hh", ".hxx", ".h"]; - if (!headerExt.every(ext => { return activeFileExt !== ext; })) { + const isHeader: boolean = ![".hpp", ".hh", ".hxx", ".h"].every(ext => { return activeFileExt !== ext; }); + if (isHeader) { return; } @@ -119,12 +119,22 @@ async function getBuildTasks(): Promise { return; } + // Get the found compilers via the whitelisted locations sent over from C++ side, selecting the compilers appropriate for this file type const activeClient: Client = getActiveClient(); - let result: vscode.Task[] = []; - - // Get the found compilers via the whitelisted locations sent over from C++ side, displaying a message if none are found const compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); - if (!compilerInfo) { + let filtered: configs.CompilerInfo[] = compilerInfo.filter(info => { + return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); + }); + + // Map CompilerInfo.path => string[]; Add user's compiler path if it's not found within the whitelist + const compilerPaths: string[] = filtered.map(info => { return info.path; }); + const userCompilerPath: string = await activeClient.getCompilerPath(); + if (!compilerPaths.find(path => { return path === userCompilerPath; })) { + compilerPaths.push(userCompilerPath); + } + + // Display a message if no paths are found + if (!compilerPaths) { const dontShowAgain: string = "Don't Show Again"; const learnMore: string = "Learn More"; const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/Cpp: build active file tasks."; @@ -149,23 +159,19 @@ async function getBuildTasks(): Promise { return; } - compilerInfo.forEach(compilerInfo => { - // Only show C++ compilers for C++ files; C compilers for C files - if ((compilerInfo.languageAssociation === 'cpp' && !activeFileIsCpp) || - (compilerInfo.languageAssociation === 'c' && !activeFileIsC)) { - return; - } - - const taskName: string = path.basename(compilerInfo.path) + " build active file"; + // Generate tasks + let result: vscode.Task[] = []; + compilerPaths.forEach(compilerPath => { + const taskName: string = path.basename(compilerPath) + " build active file"; const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/${fileBasenameNoExtension}']; const kind: vscode.TaskDefinition = { type: 'shell', label: taskName, - command: compilerInfo.path, + command: compilerPath, args: args, }; - const command: vscode.ShellExecution = new vscode.ShellExecution(compilerInfo.path, args); + const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, args); const target: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri); let task: vscode.Task = new vscode.Task(kind, target, taskName, 'C/Cpp', command, '$gcc'); task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning @@ -173,7 +179,6 @@ async function getBuildTasks(): Promise { result.push(task); }); - return result; } From 5c66968444f558cecbe345784207bc15c87905c1 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 28 Jan 2019 13:59:07 -0800 Subject: [PATCH 11/38] Refactoring; Commenting --- Extension/src/LanguageServer/extension.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 96bb61e26..252e641a1 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -104,18 +104,17 @@ async function getBuildTasks(): Promise { return; } - // Do not show build tasks for header files + // Don't offer tasks for header files const activeFileExt: string = path.extname(activeEditor.document.fileName); - const isHeader: boolean = ![".hpp", ".hh", ".hxx", ".h"].every(ext => { return activeFileExt !== ext; }); + const isHeader: boolean = ![".hpp", ".hh", ".hxx", ".h"].every(ext => activeFileExt !== ext); if (isHeader) { return; } // Don't offer tasks if the active file's extension is not a recognized C/C++ extension - let cppExtensions: string[] = [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".mm", ".ino", ".inl"]; - const activeFileIsCpp: boolean = cppExtensions.find(ext => ext === activeFileExt) !== undefined; + const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".mm", ".ino", ".inl"].find(ext => activeFileExt === ext) !== undefined; const activeFileIsC: boolean = activeFileExt === '.c'; - if (!activeFileIsCpp && activeFileExt !== '.c') { + if (!activeFileIsCpp && !activeFileIsC) { return; } From a3605fb607d72e1a319e11f79096ff81d60e66f7 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 28 Jan 2019 16:16:07 -0800 Subject: [PATCH 12/38] Remove CompilerInfo namespace; Formatting; Change return vals --- .../src/LanguageServer/configurations.ts | 7 ---- Extension/src/LanguageServer/extension.ts | 42 ++++++++++++------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 2fa48e593..673005555 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -66,13 +66,6 @@ export interface Browse { databaseFilename?: string; } -export namespace CompilerInfo { - export enum language_association { - c, - cpp - } -} - export interface CompilerInfo { path: string; languageAssociation: string; diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 252e641a1..f92615e91 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -71,6 +71,7 @@ export function activate(activationEventOccurred: boolean): void { return undefined; } }); + vscode.tasks.onDidStartTask(event => { console.log(event.execution.task.name); }); // handle "workspaceContains:/.vscode/c_cpp_properties.json" activation event. if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { @@ -101,38 +102,48 @@ export function activate(activationEventOccurred: boolean): void { async function getBuildTasks(): Promise { const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor; if (!activeEditor) { - return; + return []; } // Don't offer tasks for header files const activeFileExt: string = path.extname(activeEditor.document.fileName); const isHeader: boolean = ![".hpp", ".hh", ".hxx", ".h"].every(ext => activeFileExt !== ext); if (isHeader) { - return; + return []; } // Don't offer tasks if the active file's extension is not a recognized C/C++ extension const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".mm", ".ino", ".inl"].find(ext => activeFileExt === ext) !== undefined; const activeFileIsC: boolean = activeFileExt === '.c'; if (!activeFileIsCpp && !activeFileIsC) { - return; + return []; } - // Get the found compilers via the whitelisted locations sent over from C++ side, selecting the compilers appropriate for this file type + // Populate TaskPrimitive's based on found whitelisted-compilers, as well as user's set "compilerPath" c_cpp_property + let compilerPaths: string[]; const activeClient: Client = getActiveClient(); - const compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); - let filtered: configs.CompilerInfo[] = compilerInfo.filter(info => { - return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); - }); - - // Map CompilerInfo.path => string[]; Add user's compiler path if it's not found within the whitelist - const compilerPaths: string[] = filtered.map(info => { return info.path; }); + let compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); + if (compilerInfo) { + // Process CompilerInfo's by filtering out those with inappropriate language associations for this file, + // then map those that are left into TaskPrimitives + const languageAssociationFilter: (info: configs.CompilerInfo) => boolean = (info: configs.CompilerInfo): boolean => { + return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); + }; + compilerPaths = compilerInfo.filter(languageAssociationFilter).map(info => { return info.path; }); + } const userCompilerPath: string = await activeClient.getCompilerPath(); - if (!compilerPaths.find(path => { return path === userCompilerPath; })) { - compilerPaths.push(userCompilerPath); + if (userCompilerPath) { + if (compilerPaths) { + // Only add the compilerPath if it doesn't already exist within the list + if (compilerPaths.find(path => { return path === userCompilerPath; })) { + compilerPaths.push(userCompilerPath); + } + } else { + compilerPaths = [userCompilerPath]; + } } - // Display a message if no paths are found + // Display a message prompting the user to install compilers if none were found if (!compilerPaths) { const dontShowAgain: string = "Don't Show Again"; const learnMore: string = "Learn More"; @@ -152,10 +163,9 @@ async function getBuildTasks(): Promise { default: break; } - return true; }); } - return; + return []; } // Generate tasks From 0734201c8da68f4dcf6267baefe262b4dbb2d2d0 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 28 Jan 2019 16:59:26 -0800 Subject: [PATCH 13/38] Commenting; Add telemetry; Inverse condition --- Extension/src/LanguageServer/extension.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index f92615e91..471b1a579 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -71,7 +71,11 @@ export function activate(activationEventOccurred: boolean): void { return undefined; } }); - vscode.tasks.onDidStartTask(event => { console.log(event.execution.task.name); }); + vscode.tasks.onDidStartTask(event => { + if (event.execution.task.source === 'C/Cpp') { + telemetry.logLanguageServerEvent('buildTaskStarted'); + } + }); // handle "workspaceContains:/.vscode/c_cpp_properties.json" activation event. if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { @@ -125,7 +129,7 @@ async function getBuildTasks(): Promise { let compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); if (compilerInfo) { // Process CompilerInfo's by filtering out those with inappropriate language associations for this file, - // then map those that are left into TaskPrimitives + // then map those that are left into compilerPaths const languageAssociationFilter: (info: configs.CompilerInfo) => boolean = (info: configs.CompilerInfo): boolean => { return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); }; @@ -134,8 +138,8 @@ async function getBuildTasks(): Promise { const userCompilerPath: string = await activeClient.getCompilerPath(); if (userCompilerPath) { if (compilerPaths) { - // Only add the compilerPath if it doesn't already exist within the list - if (compilerPaths.find(path => { return path === userCompilerPath; })) { + // Only add the path if it doesn't already exist within compilerPaths + if (!compilerPaths.find(path => { return path === userCompilerPath; })) { compilerPaths.push(userCompilerPath); } } else { From dac9b22718fec6c02f7b269518db6f15869aeee9 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 29 Jan 2019 16:35:41 -0800 Subject: [PATCH 14/38] Change output program based on OS; Remove message and collect telemetry instead --- Extension/src/LanguageServer/extension.ts | 55 ++++++++++++++--------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 471b1a579..f505576ce 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -149,34 +149,45 @@ async function getBuildTasks(): Promise { // Display a message prompting the user to install compilers if none were found if (!compilerPaths) { - const dontShowAgain: string = "Don't Show Again"; - const learnMore: string = "Learn More"; - const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/Cpp: build active file tasks."; - - let showNoCompilerFoundMessage: PersistentState = new PersistentState("CPP.showNoCompilerFoundMessage", true); - if (showNoCompilerFoundMessage) { - vscode.window.showInformationMessage(message, learnMore, dontShowAgain).then(selection => { - switch (selection) { - case learnMore: - const uri: vscode.Uri = vscode.Uri.parse(`https://go.microsoft.com/fwlink/?linkid=864631`); - vscode.commands.executeCommand('vscode.open', uri); - break; - case dontShowAgain: - showNoCompilerFoundMessage.Value = false; - break; - default: - break; - } - }); - } - return []; + telemetry.logLanguageServerEvent('noCompilerFound'); + // const dontShowAgain: string = "Don't Show Again"; + // const learnMore: string = "Learn More"; + // const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/Cpp: build active file tasks."; + + // let showNoCompilerFoundMessage: PersistentState = new PersistentState("CPP.showNoCompilerFoundMessage", true); + // if (showNoCompilerFoundMessage) { + // vscode.window.showInformationMessage(message, learnMore, dontShowAgain).then(selection => { + // switch (selection) { + // case learnMore: + // const uri: vscode.Uri = vscode.Uri.parse(`https://go.microsoft.com/fwlink/?linkid=864631`); + // vscode.commands.executeCommand('vscode.open', uri); + // break; + // case dontShowAgain: + // showNoCompilerFoundMessage.Value = false; + // break; + // default: + // break; + // } + // }); + // } + // return []; + } + + // The build task output file should include a '.exe' extension on Windows + let platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation(); + let exeName: string; + if (platformInfo.platform === 'win32') { + exeName = '${fileBasenameNoExtension}'; + } else { + exeName = '${fileBasename}'; } // Generate tasks let result: vscode.Task[] = []; compilerPaths.forEach(compilerPath => { const taskName: string = path.basename(compilerPath) + " build active file"; - const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/${fileBasenameNoExtension}']; + // TODO: query OS to determine whether '.exe' should be aplied to the end of fileBasenameNoExtension + const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/' + exeName]; const kind: vscode.TaskDefinition = { type: 'shell', label: taskName, From d244b8f08c2dc5ddb34b0570726ef973048f49f5 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 29 Jan 2019 16:36:09 -0800 Subject: [PATCH 15/38] Filter out redundant compiler entries --- Extension/src/LanguageServer/extension.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index f505576ce..189f9d267 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -170,9 +170,14 @@ async function getBuildTasks(): Promise { // } // }); // } - // return []; + return []; } + // Remove redundant compiler entries based on the compiler's name (not path) + compilerPaths.filter((value, index, self) => { + return index === self.findIndex(searchValue => { return path.basename(value) === path.basename(searchValue); }); + }); + // The build task output file should include a '.exe' extension on Windows let platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation(); let exeName: string; From 3f888ef8f20d1c0c008f82e795a4be560b60129d Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Tue, 29 Jan 2019 17:39:33 -0800 Subject: [PATCH 16/38] Remove TODO; Get proper exe name; Properly reassign compilerPaths after filtering --- Extension/src/LanguageServer/extension.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 189f9d267..49240aae3 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -174,7 +174,7 @@ async function getBuildTasks(): Promise { } // Remove redundant compiler entries based on the compiler's name (not path) - compilerPaths.filter((value, index, self) => { + compilerPaths = compilerPaths.filter((value, index, self) => { return index === self.findIndex(searchValue => { return path.basename(value) === path.basename(searchValue); }); }); @@ -182,16 +182,15 @@ async function getBuildTasks(): Promise { let platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation(); let exeName: string; if (platformInfo.platform === 'win32') { - exeName = '${fileBasenameNoExtension}'; + exeName = '${fileBasenameNoExtension}.exe'; } else { - exeName = '${fileBasename}'; + exeName = '${fileBasenameNoExtension}'; } // Generate tasks let result: vscode.Task[] = []; compilerPaths.forEach(compilerPath => { const taskName: string = path.basename(compilerPath) + " build active file"; - // TODO: query OS to determine whether '.exe' should be aplied to the end of fileBasenameNoExtension const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/' + exeName]; const kind: vscode.TaskDefinition = { type: 'shell', From f7a595f901883a3250bb9962c642c8ae6c540027 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Tue, 29 Jan 2019 18:16:52 -0800 Subject: [PATCH 17/38] Commenting; Fix cwd mingw bug --- Extension/src/LanguageServer/extension.ts | 29 +++++++++++++---------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 49240aae3..d2f795c91 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -101,7 +101,7 @@ export function activate(activationEventOccurred: boolean): void { } /** - * Generate tasks to build the current file based on the user's detected compilers, the user's set compiler path, and the current file's extension + * Generate tasks to build the current file based on the user's detected compilers, the user's compilerPath setting, and the current file's extension */ async function getBuildTasks(): Promise { const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor; @@ -123,22 +123,21 @@ async function getBuildTasks(): Promise { return []; } - // Populate TaskPrimitive's based on found whitelisted-compilers, as well as user's set "compilerPath" c_cpp_property + // Get a list of compilers found from the C++ side, then filter them based on the file type to get a reduced list appropriate for the active file let compilerPaths: string[]; const activeClient: Client = getActiveClient(); let compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); if (compilerInfo) { - // Process CompilerInfo's by filtering out those with inappropriate language associations for this file, - // then map those that are left into compilerPaths const languageAssociationFilter: (info: configs.CompilerInfo) => boolean = (info: configs.CompilerInfo): boolean => { return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); }; compilerPaths = compilerInfo.filter(languageAssociationFilter).map(info => { return info.path; }); } + + // Add the user's compilerPath setting to compilerPaths if it is not a duplicate const userCompilerPath: string = await activeClient.getCompilerPath(); if (userCompilerPath) { if (compilerPaths) { - // Only add the path if it doesn't already exist within compilerPaths if (!compilerPaths.find(path => { return path === userCompilerPath; })) { compilerPaths.push(userCompilerPath); } @@ -147,9 +146,18 @@ async function getBuildTasks(): Promise { } } - // Display a message prompting the user to install compilers if none were found + // Remove redundant compiler entries based on the compiler's name (not path) + if (compilerPaths) { + compilerPaths = compilerPaths.filter((value, index, self) => { + // N^2 "unique" algorithm. Iterate over array. Compare current element to another element that happens to have the same basename. + // If the indices don't match, there must be a duplicate. Remove the current element. + return index === self.findIndex(searchValue => { return path.basename(value) === path.basename(searchValue); }); + }); + } + if (!compilerPaths) { - telemetry.logLanguageServerEvent('noCompilerFound'); + telemetry.logLanguageServerEvent('noCompilerFound'); // Don't prompt a message yet until we can make a data-based decision + // Display a message prompting the user to install compilers if none were found // const dontShowAgain: string = "Don't Show Again"; // const learnMore: string = "Learn More"; // const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/Cpp: build active file tasks."; @@ -173,11 +181,6 @@ async function getBuildTasks(): Promise { return []; } - // Remove redundant compiler entries based on the compiler's name (not path) - compilerPaths = compilerPaths.filter((value, index, self) => { - return index === self.findIndex(searchValue => { return path.basename(value) === path.basename(searchValue); }); - }); - // The build task output file should include a '.exe' extension on Windows let platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation(); let exeName: string; @@ -199,7 +202,7 @@ async function getBuildTasks(): Promise { args: args, }; - const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, args); + const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, args, { cwd: path.dirname(compilerPath) }); const target: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri); let task: vscode.Task = new vscode.Task(kind, target, taskName, 'C/Cpp', command, '$gcc'); task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning From 7ca5f9bcbe83fcb456dd93220445511f78f9687a Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Wed, 30 Jan 2019 11:10:55 -0800 Subject: [PATCH 18/38] Commenting; Refactor --- Extension/src/LanguageServer/extension.ts | 25 +++++++++-------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index d2f795c91..d08ce0a17 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -124,37 +124,32 @@ async function getBuildTasks(): Promise { } // Get a list of compilers found from the C++ side, then filter them based on the file type to get a reduced list appropriate for the active file + // then finally remove duplicate compiler names let compilerPaths: string[]; const activeClient: Client = getActiveClient(); + const userCompilerPath: string = await activeClient.getCompilerPath(); let compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); if (compilerInfo) { const languageAssociationFilter: (info: configs.CompilerInfo) => boolean = (info: configs.CompilerInfo): boolean => { return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); }; compilerPaths = compilerInfo.filter(languageAssociationFilter).map(info => { return info.path; }); - } - // Add the user's compilerPath setting to compilerPaths if it is not a duplicate - const userCompilerPath: string = await activeClient.getCompilerPath(); - if (userCompilerPath) { - if (compilerPaths) { - if (!compilerPaths.find(path => { return path === userCompilerPath; })) { - compilerPaths.push(userCompilerPath); - } - } else { - compilerPaths = [userCompilerPath]; + if (userCompilerPath) { + compilerPaths.push(userCompilerPath); } - } - // Remove redundant compiler entries based on the compiler's name (not path) - if (compilerPaths) { compilerPaths = compilerPaths.filter((value, index, self) => { - // N^2 "unique" algorithm. Iterate over array. Compare current element to another element that happens to have the same basename. - // If the indices don't match, there must be a duplicate. Remove the current element. + // N^2 "unique" algorithm. Iterate over array. Compare current element to other elements looking for one with an equivalent basename + // If found and the indices don't match, there must be a duplicate. Remove the current element. return index === self.findIndex(searchValue => { return path.basename(value) === path.basename(searchValue); }); }); + } else if (userCompilerPath) { + compilerPaths = [userCompilerPath]; } + + if (!compilerPaths) { telemetry.logLanguageServerEvent('noCompilerFound'); // Don't prompt a message yet until we can make a data-based decision // Display a message prompting the user to install compilers if none were found From e282c1f146d28278f2db08d021879f88d5dbceda Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Wed, 30 Jan 2019 11:12:07 -0800 Subject: [PATCH 19/38] Mark compilerInfo const --- Extension/src/LanguageServer/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index d08ce0a17..40a23fc84 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -128,7 +128,7 @@ async function getBuildTasks(): Promise { let compilerPaths: string[]; const activeClient: Client = getActiveClient(); const userCompilerPath: string = await activeClient.getCompilerPath(); - let compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); + const compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); if (compilerInfo) { const languageAssociationFilter: (info: configs.CompilerInfo) => boolean = (info: configs.CompilerInfo): boolean => { return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); From 61cfd4fdac93a2e0c5b54768431a52e821db30cd Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Wed, 30 Jan 2019 12:54:26 -0800 Subject: [PATCH 20/38] Remove whitespace; Remove bad comment --- Extension/src/LanguageServer/extension.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 40a23fc84..2e0cfed23 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -57,12 +57,11 @@ export function activate(activationEventOccurred: boolean): void { tempCommands.push(vscode.workspace.onDidOpenTextDocument(d => onDidOpenTextDocument(d))); // Check if an activation event has already occurred. - if (activationEventOccurred) { + if (activationEventOccurred) { onActivationEvent(); return; } - // let buildPromise: Thenable | undefined = undefined; taskProvider = vscode.tasks.registerTaskProvider('shell', { provideTasks: () => { return getBuildTasks(); From ca2daeab08b23a5be2945e225032f1ebbb59b980 Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Wed, 30 Jan 2019 12:56:35 -0800 Subject: [PATCH 21/38] Remove whitespace --- Extension/src/LanguageServer/extension.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 2e0cfed23..74b6e52a3 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -147,8 +147,6 @@ async function getBuildTasks(): Promise { compilerPaths = [userCompilerPath]; } - - if (!compilerPaths) { telemetry.logLanguageServerEvent('noCompilerFound'); // Don't prompt a message yet until we can make a data-based decision // Display a message prompting the user to install compilers if none were found From 0adc1329d9e948654703e9061cbc4cd1c63eba5f Mon Sep 17 00:00:00 2001 From: Griffin Downs Date: Wed, 30 Jan 2019 13:34:30 -0800 Subject: [PATCH 22/38] Replace unique algorithm with a map --- Extension/src/LanguageServer/extension.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 74b6e52a3..f6feaf4ec 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -138,11 +138,11 @@ async function getBuildTasks(): Promise { compilerPaths.push(userCompilerPath); } - compilerPaths = compilerPaths.filter((value, index, self) => { - // N^2 "unique" algorithm. Iterate over array. Compare current element to other elements looking for one with an equivalent basename - // If found and the indices don't match, there must be a duplicate. Remove the current element. - return index === self.findIndex(searchValue => { return path.basename(value) === path.basename(searchValue); }); + let map: Map = new Map(); + compilerPaths.forEach(value => { + map.has(path.basename(value)) ? map[path.basename(value)] = value : map.set(path.basename(value), value); }); + compilerPaths = [...map.values()]; } else if (userCompilerPath) { compilerPaths = [userCompilerPath]; } From e180fee86d2453a3f66b9cf9e628dae5ece59883 Mon Sep 17 00:00:00 2001 From: grdowns Date: Wed, 30 Jan 2019 13:44:35 -0800 Subject: [PATCH 23/38] pre-compute basename --- Extension/src/LanguageServer/extension.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index f6feaf4ec..ccd7f0ecd 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -140,7 +140,8 @@ async function getBuildTasks(): Promise { let map: Map = new Map(); compilerPaths.forEach(value => { - map.has(path.basename(value)) ? map[path.basename(value)] = value : map.set(path.basename(value), value); + const basename: string = path.basename(value); + map.has(basename) ? map[basename] = value : map.set(basename, value); }); compilerPaths = [...map.values()]; } else if (userCompilerPath) { From 459322d16fb673686ad4699b4f622bf076808590 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Jan 2019 18:47:04 -0800 Subject: [PATCH 24/38] Move comment --- Extension/src/LanguageServer/extension.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index ccd7f0ecd..a53fc7cee 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -149,7 +149,8 @@ async function getBuildTasks(): Promise { } if (!compilerPaths) { - telemetry.logLanguageServerEvent('noCompilerFound'); // Don't prompt a message yet until we can make a data-based decision + // Don't prompt a message yet until we can make a data-based decision + telemetry.logLanguageServerEvent('noCompilerFound'); // Display a message prompting the user to install compilers if none were found // const dontShowAgain: string = "Don't Show Again"; // const learnMore: string = "Learn More"; From 2f94cc4b4fd38bf66a8a6221b2070df069ddaa91 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Jan 2019 19:37:31 -0800 Subject: [PATCH 25/38] Commenting; Ensure user's compilerPath setting is used --- Extension/src/LanguageServer/extension.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index a53fc7cee..e5fa68ebf 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -122,8 +122,8 @@ async function getBuildTasks(): Promise { return []; } - // Get a list of compilers found from the C++ side, then filter them based on the file type to get a reduced list appropriate for the active file - // then finally remove duplicate compiler names + // Get a list of compilers found from the C++ side, then filter them based on the file type to get a reduced list appropriate + // for the active file, remove duplicate compiler names, then finally add the user's compilerPath setting let compilerPaths: string[]; const activeClient: Client = getActiveClient(); const userCompilerPath: string = await activeClient.getCompilerPath(); @@ -134,15 +134,18 @@ async function getBuildTasks(): Promise { }; compilerPaths = compilerInfo.filter(languageAssociationFilter).map(info => { return info.path; }); + let map: Map = new Map(); + const insertOrAssignEntry: (compilerPath: string) => void = (compilerPath: string): void => { + const basename: string = path.basename(compilerPath); + map.has(basename) ? map[basename] = compilerPath : map.set(basename, compilerPath); + }; + compilerPaths.forEach(insertOrAssignEntry); + + // Ensure that the user's compilerPath setting is used by inserting/assigning last if (userCompilerPath) { - compilerPaths.push(userCompilerPath); + insertOrAssignEntry(userCompilerPath); } - let map: Map = new Map(); - compilerPaths.forEach(value => { - const basename: string = path.basename(value); - map.has(basename) ? map[basename] = value : map.set(basename, value); - }); compilerPaths = [...map.values()]; } else if (userCompilerPath) { compilerPaths = [userCompilerPath]; From 898f679e48641b8c6b59315157473a78b5312f0c Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Jan 2019 19:38:58 -0800 Subject: [PATCH 26/38] Use indexOf instead of find --- Extension/src/LanguageServer/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index e5fa68ebf..f6854363f 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -116,7 +116,7 @@ async function getBuildTasks(): Promise { } // Don't offer tasks if the active file's extension is not a recognized C/C++ extension - const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".mm", ".ino", ".inl"].find(ext => activeFileExt === ext) !== undefined; + const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".mm", ".ino", ".inl"].indexOf(activeFileExt) !== -1; const activeFileIsC: boolean = activeFileExt === '.c'; if (!activeFileIsCpp && !activeFileIsC) { return []; From a27bb84c3cf4afb86988b38d69d9c313573fa00c Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Jan 2019 19:39:37 -0800 Subject: [PATCH 27/38] Simplify isHeader calculation by using some instead of every --- Extension/src/LanguageServer/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index f6854363f..a627310ba 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -110,7 +110,7 @@ async function getBuildTasks(): Promise { // Don't offer tasks for header files const activeFileExt: string = path.extname(activeEditor.document.fileName); - const isHeader: boolean = ![".hpp", ".hh", ".hxx", ".h"].every(ext => activeFileExt !== ext); + const isHeader: boolean = [".hpp", ".hh", ".hxx", ".h"].some(ext => activeFileExt === ext); if (isHeader) { return []; } From 81d75a55455a5f441df718586f28967c1148729f Mon Sep 17 00:00:00 2001 From: = Date: Wed, 30 Jan 2019 19:42:17 -0800 Subject: [PATCH 28/38] Don't redundantly check extensions; Use some instead of indexOf --- Extension/src/LanguageServer/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index a627310ba..29568c1f1 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -116,7 +116,7 @@ async function getBuildTasks(): Promise { } // Don't offer tasks if the active file's extension is not a recognized C/C++ extension - const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".mm", ".ino", ".inl"].indexOf(activeFileExt) !== -1; + const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => activeFileExt === ext); const activeFileIsC: boolean = activeFileExt === '.c'; if (!activeFileIsCpp && !activeFileIsC) { return []; From 70790996b41a67712b6f87ede791af3368f42d19 Mon Sep 17 00:00:00 2001 From: grdowns Date: Fri, 1 Feb 2019 00:06:25 -0500 Subject: [PATCH 29/38] Add comment punctuation Use file macro instead of fileDirName and fileBaseName Change path provider name; expose cwd in definition Add shell task definition (it's not built into vs code apparently) --- Extension/package.json | 21 ++++++++++++++++- Extension/src/LanguageServer/extension.ts | 28 ++++++++++++----------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index 6e68a19f0..a1ab24930 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -43,6 +43,25 @@ ], "main": "./out/src/main", "contributes": { + "taskDefinitions": [ + { + "type": "shell", + "properties": { + "label": { + "type": "string" + }, + "command": { + "type": "string" + }, + "args": { + "type": "array" + }, + "cwd": { + "type": "string" + } + } + } + ], "problemMatchers": [ { "name": "gcc", @@ -1577,4 +1596,4 @@ "binaries": [] } ] -} +} \ No newline at end of file diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index ed70083ee..ffaea4aa4 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -63,7 +63,7 @@ export function activate(activationEventOccurred: boolean): void { return; } - taskProvider = vscode.tasks.registerTaskProvider('shell', { + taskProvider = vscode.tasks.registerTaskProvider('C/Cpp', { provideTasks: () => { return getBuildTasks(); }, @@ -101,7 +101,7 @@ export function activate(activationEventOccurred: boolean): void { } /** - * Generate tasks to build the current file based on the user's detected compilers, the user's compilerPath setting, and the current file's extension + * Generate tasks to build the current file based on the user's detected compilers, the user's compilerPath setting, and the current file's extension. */ async function getBuildTasks(): Promise { const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor; @@ -109,14 +109,14 @@ async function getBuildTasks(): Promise { return []; } - // Don't offer tasks for header files + // Don't offer tasks for header files. const activeFileExt: string = path.extname(activeEditor.document.fileName); const isHeader: boolean = [".hpp", ".hh", ".hxx", ".h"].some(ext => activeFileExt === ext); if (isHeader) { return []; } - // Don't offer tasks if the active file's extension is not a recognized C/C++ extension + // Don't offer tasks if the active file's extension is not a recognized C/C++ extension. const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => activeFileExt === ext); const activeFileIsC: boolean = activeFileExt === '.c'; if (!activeFileIsCpp && !activeFileIsC) { @@ -124,7 +124,7 @@ async function getBuildTasks(): Promise { } // Get a list of compilers found from the C++ side, then filter them based on the file type to get a reduced list appropriate - // for the active file, remove duplicate compiler names, then finally add the user's compilerPath setting + // for the active file, remove duplicate compiler names, then finally add the user's compilerPath setting. let compilerPaths: string[]; const activeClient: Client = getActiveClient(); const userCompilerPath: string = await activeClient.getCompilerPath(); @@ -142,7 +142,7 @@ async function getBuildTasks(): Promise { }; compilerPaths.forEach(insertOrAssignEntry); - // Ensure that the user's compilerPath setting is used by inserting/assigning last + // Ensure that the user's compilerPath setting is used by inserting/assigning last. if (userCompilerPath) { insertOrAssignEntry(userCompilerPath); } @@ -153,9 +153,9 @@ async function getBuildTasks(): Promise { } if (!compilerPaths) { - // Don't prompt a message yet until we can make a data-based decision + // Don't prompt a message yet until we can make a data-based decision. telemetry.logLanguageServerEvent('noCompilerFound'); - // Display a message prompting the user to install compilers if none were found + // Display a message prompting the user to install compilers if none were found. // const dontShowAgain: string = "Don't Show Again"; // const learnMore: string = "Learn More"; // const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/Cpp: build active file tasks."; @@ -179,7 +179,7 @@ async function getBuildTasks(): Promise { return []; } - // The build task output file should include a '.exe' extension on Windows + // The build task output file should include a '.exe' extension on Windows. let platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation(); let exeName: string; if (platformInfo.platform === 'win32') { @@ -188,22 +188,24 @@ async function getBuildTasks(): Promise { exeName = '${fileBasenameNoExtension}'; } - // Generate tasks + // Generate tasks. let result: vscode.Task[] = []; compilerPaths.forEach(compilerPath => { const taskName: string = path.basename(compilerPath) + " build active file"; - const args: string[] = ['-g', '${fileDirname}/${fileBasename}', '-o', '${fileDirname}/' + exeName]; + const args: string[] = ['-g', '${file}', '-o', '${fileDirname}/' + exeName]; + const cwd: string = path.dirname(compilerPath); const kind: vscode.TaskDefinition = { type: 'shell', label: taskName, command: compilerPath, args: args, + cwd: cwd }; - const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, args, { cwd: path.dirname(compilerPath) }); + const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, [...args], { cwd: cwd }); const target: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri); let task: vscode.Task = new vscode.Task(kind, target, taskName, 'C/Cpp', command, '$gcc'); - task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning + task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning. task.group = vscode.TaskGroup.Build; result.push(task); From a9a079480a3fd16c165aee90e79981fd74ef922e Mon Sep 17 00:00:00 2001 From: grdowns Date: Wed, 6 Feb 2019 15:58:47 -0500 Subject: [PATCH 30/38] Lowercase file extension to match; Count extensionless files as headers --- Extension/src/LanguageServer/extension.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index ffaea4aa4..80b5cc8e7 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -110,8 +110,8 @@ async function getBuildTasks(): Promise { } // Don't offer tasks for header files. - const activeFileExt: string = path.extname(activeEditor.document.fileName); - const isHeader: boolean = [".hpp", ".hh", ".hxx", ".h"].some(ext => activeFileExt === ext); + const activeFileExt: string = path.extname(activeEditor.document.fileName).toLowerCase(); + const isHeader: boolean = [".hpp", ".hh", ".hxx", ".h", ""].some(ext => activeFileExt === ext); if (isHeader) { return []; } From 7b4fad461066513816a4489d5d74b278ef7edc45 Mon Sep 17 00:00:00 2001 From: grdowns Date: Wed, 6 Feb 2019 16:16:35 -0500 Subject: [PATCH 31/38] Add newline --- Extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/package.json b/Extension/package.json index a1ab24930..1a822f18c 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -1596,4 +1596,4 @@ "binaries": [] } ] -} \ No newline at end of file +} From b234685cb64a1c7eb65dac44f4dedd6ff6921066 Mon Sep 17 00:00:00 2001 From: grdowns Date: Mon, 11 Feb 2019 15:58:42 -0500 Subject: [PATCH 32/38] Change CompilerInfo to KnownCompiler --- Extension/src/LanguageServer/client.ts | 8 ++++---- Extension/src/LanguageServer/configurations.ts | 16 ++++++++-------- Extension/src/LanguageServer/extension.ts | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index e6df4f039..12c8736d3 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -203,7 +203,7 @@ export interface Client { provideCustomConfiguration(document: vscode.TextDocument): Promise; getCurrentConfigName(): Thenable; getCompilerPath(): Thenable; - getCompilerInfo(): Thenable; + getKnownCompilers(): Thenable; takeOwnership(document: vscode.TextDocument): void; queueTask(task: () => Thenable): Thenable; requestWhenReady(request: () => Thenable): Thenable; @@ -668,8 +668,8 @@ class DefaultClient implements Client { return this.queueTask(() => Promise.resolve(this.configuration.CompilerPath)); } - public getCompilerInfo(): Thenable { - return this.queueTask(() => Promise.resolve(this.configuration.CompilerInfo)); + public getKnownCompilers(): Thenable { + return this.queueTask(() => Promise.resolve(this.configuration.KnownCompiler)); } /** @@ -1361,7 +1361,7 @@ class NullClient implements Client { provideCustomConfiguration(document: vscode.TextDocument): Promise { return Promise.resolve(); } getCurrentConfigName(): Thenable { return Promise.resolve(""); } getCompilerPath(): Thenable { return Promise.resolve(""); } - getCompilerInfo(): Thenable { return Promise.resolve([]); } + getKnownCompilers(): Thenable { return Promise.resolve([]); } takeOwnership(document: vscode.TextDocument): void {} queueTask(task: () => Thenable): Thenable { return task(); } requestWhenReady(request: () => Thenable): Thenable { return; } diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 5a4fbffa9..7c3dad070 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -46,7 +46,7 @@ export interface ConfigurationJson { export interface Configuration { name: string; compilerPath?: string; - compilerInfo?: CompilerInfo[]; + knownCompilers?: KnownCompiler[]; cStandard?: string; cppStandard?: string; includePath?: string[]; @@ -66,14 +66,14 @@ export interface Browse { databaseFilename?: string; } -export interface CompilerInfo { +export interface KnownCompiler { path: string; languageAssociation: string; } export interface CompilerDefaults { compilerPath: string; - compilerInfo: CompilerInfo[]; + knownCompilers: KnownCompiler[]; cStandard: string; cppStandard: string; includes: string[]; @@ -92,7 +92,7 @@ export class CppProperties { private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails. private compileCommandFileWatchers: fs.FSWatcher[] = []; private defaultCompilerPath: string = null; - private compilerInfo: CompilerInfo[] = null; + private knownCompilers: KnownCompiler[] = null; private defaultCStandard: string = null; private defaultCppStandard: string = null; private defaultIncludes: string[] = null; @@ -156,7 +156,7 @@ export class CppProperties { public get CurrentConfigurationIndex(): number { return this.currentConfigurationIndex.Value; } public get CurrentConfiguration(): Configuration { return this.Configurations[this.CurrentConfigurationIndex]; } public get CompilerPath(): string { return this.CurrentConfiguration.compilerPath; } - public get CompilerInfo(): CompilerInfo[] { return this.compilerInfo; } + public get KnownCompiler(): KnownCompiler[] { return this.knownCompilers; } public get CurrentConfigurationProvider(): string|null { if (this.CurrentConfiguration.configurationProvider) { @@ -173,7 +173,7 @@ export class CppProperties { public set CompilerDefaults(compilerDefaults: CompilerDefaults) { this.defaultCompilerPath = compilerDefaults.compilerPath; - this.compilerInfo = compilerDefaults.compilerInfo; + this.knownCompilers = compilerDefaults.knownCompilers; this.defaultCStandard = compilerDefaults.cStandard; this.defaultCppStandard = compilerDefaults.cppStandard; this.defaultIncludes = compilerDefaults.includes; @@ -259,8 +259,8 @@ export class CppProperties { // don't set a default when compileCommands is in use. configuration.compilerPath = this.defaultCompilerPath; } - if (this.compilerInfo) { - configuration.compilerInfo = this.compilerInfo; + if (this.knownCompilers) { + configuration.knownCompilers = this.knownCompilers; } if (isUnset(settings.defaultCStandard) && this.defaultCStandard) { configuration.cStandard = this.defaultCStandard; diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 80b5cc8e7..aea9ec13a 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -128,12 +128,12 @@ async function getBuildTasks(): Promise { let compilerPaths: string[]; const activeClient: Client = getActiveClient(); const userCompilerPath: string = await activeClient.getCompilerPath(); - const compilerInfo: configs.CompilerInfo[] = await activeClient.getCompilerInfo(); - if (compilerInfo) { - const languageAssociationFilter: (info: configs.CompilerInfo) => boolean = (info: configs.CompilerInfo): boolean => { + const knownCompilers: configs.KnownCompiler[] = await activeClient.getKnownCompilers(); + if (knownCompilers) { + const languageAssociationFilter: (info: configs.KnownCompiler) => boolean = (info: configs.KnownCompiler): boolean => { return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); }; - compilerPaths = compilerInfo.filter(languageAssociationFilter).map(info => { return info.path; }); + compilerPaths = knownCompilers.filter(languageAssociationFilter).map(info => { return info.path; }); let map: Map = new Map(); const insertOrAssignEntry: (compilerPath: string) => void = (compilerPath: string): void => { From 16a06b6294e69bebaa2b7a25315c1676acd7cf4b Mon Sep 17 00:00:00 2001 From: grdowns Date: Mon, 11 Feb 2019 16:47:31 -0500 Subject: [PATCH 33/38] Support ambiguous file extension --- Extension/src/LanguageServer/extension.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index aea9ec13a..ffacfa888 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -110,16 +110,21 @@ async function getBuildTasks(): Promise { } // Don't offer tasks for header files. - const activeFileExt: string = path.extname(activeEditor.document.fileName).toLowerCase(); - const isHeader: boolean = [".hpp", ".hh", ".hxx", ".h", ""].some(ext => activeFileExt === ext); + const activeFileExt: string = path.extname(activeEditor.document.fileName); + const activeFileExtLower: string = activeFileExt.toLowerCase(); + const isHeader: boolean = [".hpp", ".hh", ".hxx", ".h", ""].some(ext => activeFileExtLower === ext); if (isHeader) { return []; } // Don't offer tasks if the active file's extension is not a recognized C/C++ extension. - const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => activeFileExt === ext); - const activeFileIsC: boolean = activeFileExt === '.c'; - if (!activeFileIsCpp && !activeFileIsC) { + let activeFileLanguage: string; + const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => activeFileExtLower === ext); + if (activeFileIsCpp) { + activeFileLanguage = 'cpp'; + } else if (activeFileExt === '.c') { + activeFileLanguage = 'c'; + } else if (activeFileExt !== '.C') { // Ambiguous file extension return []; } @@ -131,7 +136,7 @@ async function getBuildTasks(): Promise { const knownCompilers: configs.KnownCompiler[] = await activeClient.getKnownCompilers(); if (knownCompilers) { const languageAssociationFilter: (info: configs.KnownCompiler) => boolean = (info: configs.KnownCompiler): boolean => { - return (info.languageAssociation === 'cpp' && activeFileIsCpp) || (info.languageAssociation === 'c' && activeFileIsC); + return !activeFileLanguage || info.languageAssociation === activeFileLanguage; }; compilerPaths = knownCompilers.filter(languageAssociationFilter).map(info => { return info.path; }); From ce4e5da7ecd939cd2c6451b62924e75ba0737ccc Mon Sep 17 00:00:00 2001 From: grdowns Date: Mon, 11 Feb 2019 16:51:00 -0500 Subject: [PATCH 34/38] Early out for extensionless files --- Extension/src/LanguageServer/extension.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index ffacfa888..243a5afc0 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -109,8 +109,12 @@ async function getBuildTasks(): Promise { return []; } - // Don't offer tasks for header files. const activeFileExt: string = path.extname(activeEditor.document.fileName); + if (!activeFileExt) { + return; + } + + // Don't offer tasks for header files. const activeFileExtLower: string = activeFileExt.toLowerCase(); const isHeader: boolean = [".hpp", ".hh", ".hxx", ".h", ""].some(ext => activeFileExtLower === ext); if (isHeader) { From 024a0eb142494dccb7312443ffa8fb9e126a41ef Mon Sep 17 00:00:00 2001 From: grdowns Date: Mon, 11 Feb 2019 17:41:38 -0500 Subject: [PATCH 35/38] Commenting --- Extension/src/LanguageServer/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 243a5afc0..1d0c55920 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -128,7 +128,7 @@ async function getBuildTasks(): Promise { activeFileLanguage = 'cpp'; } else if (activeFileExt === '.c') { activeFileLanguage = 'c'; - } else if (activeFileExt !== '.C') { // Ambiguous file extension + } else if (activeFileExt !== '.C') { // Ambiguous file extension. return []; } From 58cd0bc022d5ef5fd7c958add0b5b1845b6b1bf1 Mon Sep 17 00:00:00 2001 From: grdowns Date: Tue, 12 Feb 2019 17:10:32 -0500 Subject: [PATCH 36/38] Commenting; Rename telemetry event --- Extension/src/LanguageServer/extension.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 1d0c55920..e151648f9 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -128,7 +128,7 @@ async function getBuildTasks(): Promise { activeFileLanguage = 'cpp'; } else if (activeFileExt === '.c') { activeFileLanguage = 'c'; - } else if (activeFileExt !== '.C') { // Ambiguous file extension. + } else if (activeFileExt !== '.C') { // Ambiguous file extension. Show both C and C++ compilers for .C files. return []; } @@ -163,7 +163,7 @@ async function getBuildTasks(): Promise { if (!compilerPaths) { // Don't prompt a message yet until we can make a data-based decision. - telemetry.logLanguageServerEvent('noCompilerFound'); + telemetry.logLanguageServerEvent('buildTaskNoCompiler'); // Display a message prompting the user to install compilers if none were found. // const dontShowAgain: string = "Don't Show Again"; // const learnMore: string = "Learn More"; From 0ec7b4f8d6e66b20fa17191f9066d7e1a1254feb Mon Sep 17 00:00:00 2001 From: grdowns Date: Wed, 13 Feb 2019 04:05:37 -0500 Subject: [PATCH 37/38] Change languageAssociation to isC --- .../src/LanguageServer/configurations.ts | 2 +- Extension/src/LanguageServer/extension.ts | 39 ++++++++++--------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 7c3dad070..9a5029077 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -68,7 +68,7 @@ export interface Browse { export interface KnownCompiler { path: string; - languageAssociation: string; + isC: boolean; } export interface CompilerDefaults { diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index e151648f9..7fa71f033 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -104,31 +104,34 @@ export function activate(activationEventOccurred: boolean): void { * Generate tasks to build the current file based on the user's detected compilers, the user's compilerPath setting, and the current file's extension. */ async function getBuildTasks(): Promise { - const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor; - if (!activeEditor) { + const editor: vscode.TextEditor = vscode.window.activeTextEditor; + if (!editor) { return []; } - const activeFileExt: string = path.extname(activeEditor.document.fileName); - if (!activeFileExt) { + const fileExt: string = path.extname(editor.document.fileName); + if (!fileExt) { return; } // Don't offer tasks for header files. - const activeFileExtLower: string = activeFileExt.toLowerCase(); - const isHeader: boolean = [".hpp", ".hh", ".hxx", ".h", ""].some(ext => activeFileExtLower === ext); + const fileExtLower: string = fileExt.toLowerCase(); + const isHeader: boolean = !fileExt || [".hpp", ".hh", ".hxx", ".h", ""].some(ext => fileExtLower === ext); if (isHeader) { return []; } // Don't offer tasks if the active file's extension is not a recognized C/C++ extension. - let activeFileLanguage: string; - const activeFileIsCpp: boolean = [".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => activeFileExtLower === ext); - if (activeFileIsCpp) { - activeFileLanguage = 'cpp'; - } else if (activeFileExt === '.c') { - activeFileLanguage = 'c'; - } else if (activeFileExt !== '.C') { // Ambiguous file extension. Show both C and C++ compilers for .C files. + let fileIsCpp: boolean; + let fileIsC: boolean; + if (fileExt === ".C") { // ".C" file extensions are both C and C++. + fileIsCpp = true; + fileIsC = true; + } else { + fileIsCpp = [".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => fileExtLower === ext); + fileIsC = fileExtLower === ".c"; + } + if (!(fileIsCpp || fileIsC)) { return []; } @@ -137,12 +140,10 @@ async function getBuildTasks(): Promise { let compilerPaths: string[]; const activeClient: Client = getActiveClient(); const userCompilerPath: string = await activeClient.getCompilerPath(); - const knownCompilers: configs.KnownCompiler[] = await activeClient.getKnownCompilers(); + let knownCompilers: configs.KnownCompiler[] = await activeClient.getKnownCompilers(); if (knownCompilers) { - const languageAssociationFilter: (info: configs.KnownCompiler) => boolean = (info: configs.KnownCompiler): boolean => { - return !activeFileLanguage || info.languageAssociation === activeFileLanguage; - }; - compilerPaths = knownCompilers.filter(languageAssociationFilter).map(info => { return info.path; }); + knownCompilers = knownCompilers.filter(info => { return (fileIsCpp && !info.isC) || (fileIsC && info.isC); }); + compilerPaths = knownCompilers.map(info => { return info.path; }); let map: Map = new Map(); const insertOrAssignEntry: (compilerPath: string) => void = (compilerPath: string): void => { @@ -163,7 +164,7 @@ async function getBuildTasks(): Promise { if (!compilerPaths) { // Don't prompt a message yet until we can make a data-based decision. - telemetry.logLanguageServerEvent('buildTaskNoCompiler'); + telemetry.logLanguageServerEvent('noCompilerFound'); // Display a message prompting the user to install compilers if none were found. // const dontShowAgain: string = "Don't Show Again"; // const learnMore: string = "Learn More"; From 26da4db37594ed868da98561392ab79eb714943d Mon Sep 17 00:00:00 2001 From: grdowns Date: Wed, 13 Feb 2019 10:59:07 -0500 Subject: [PATCH 38/38] Fix bug where cwd was not used; Add comment --- Extension/package.json | 4 ++-- Extension/src/LanguageServer/extension.ts | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index 763f740d3..1c6283436 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -56,8 +56,8 @@ "args": { "type": "array" }, - "cwd": { - "type": "string" + "options": { + "type": "array" } } } diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 7fa71f033..6ad6af241 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -68,6 +68,7 @@ export function activate(activationEventOccurred: boolean): void { return getBuildTasks(); }, resolveTask(task: vscode.Task): vscode.Task { + // Currently cannot implement because VS Code does not call this. Can implement custom output file directory when enabled. return undefined; } }); @@ -209,7 +210,7 @@ async function getBuildTasks(): Promise { label: taskName, command: compilerPath, args: args, - cwd: cwd + options: {"cwd": cwd} }; const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, [...args], { cwd: cwd });