44 * ------------------------------------------------------------------------------------------ */
55import * as path from 'path' ;
66import {
7- TaskDefinition , Task , TaskGroup , WorkspaceFolder , ShellExecution , Uri , workspace ,
7+ TaskDefinition , Task , TaskGroup , ShellExecution , Uri , workspace ,
88 TaskProvider , TaskScope , CustomExecution , ProcessExecution , TextEditor , Pseudoterminal , EventEmitter , Event , TerminalDimensions , window
99} from 'vscode' ;
1010import * as os from 'os' ;
@@ -15,6 +15,10 @@ import * as configs from './configurations';
1515import * as ext from './extension' ;
1616import * as cp from "child_process" ;
1717import { OtherSettings } from './settings' ;
18+ import * as nls from 'vscode-nls' ;
19+
20+ nls . config ( { messageFormat : nls . MessageFormat . bundle , bundleFormat : nls . BundleFormat . standalone } ) ( ) ;
21+ const localize : nls . LocalizeFunc = nls . loadMessageBundle ( ) ;
1822
1923export interface CppBuildTaskDefinition extends TaskDefinition {
2024 type : string ;
@@ -156,7 +160,7 @@ export class CppBuildTaskProvider implements TaskProvider {
156160
157161 if ( ! definition ) {
158162 const taskLabel : string = ( ( appendSourceToName && ! compilerPathBase . startsWith ( CppBuildTaskProvider . CppBuildSourceStr ) ) ?
159- CppBuildTaskProvider . CppBuildSourceStr + ": " : "" ) + compilerPathBase + " build active file" ;
163+ CppBuildTaskProvider . CppBuildSourceStr + ": " : "" ) + compilerPathBase + " " + localize ( "build_active_file" , " build active file") ;
160164 const filePath : string = path . join ( '${fileDirname}' , '${fileBasenameNoExtension}' ) ;
161165 const isWindows : boolean = os . platform ( ) === 'win32' ;
162166 let args : string [ ] = isCl ? [ '/Zi' , '/EHsc' , '/Fe:' , filePath + '.exe' , '${file}' ] : [ '-g' , '${file}' , '-o' , filePath + ( isWindows ? '.exe' : '' ) ] ;
@@ -185,13 +189,13 @@ export class CppBuildTaskProvider implements TaskProvider {
185189
186190 const scope : TaskScope = TaskScope . Workspace ;
187191 const task : CppBuildTask = new Task ( definition , scope , definition . label , CppBuildTaskProvider . CppBuildSourceStr ,
188- new CustomExecution ( async ( ) : Promise < Pseudoterminal > =>
192+ new CustomExecution ( async ( resolvedDefinition : TaskDefinition ) : Promise < Pseudoterminal > =>
189193 // When the task is executed, this callback will run. Here, we setup for running the task.
190- new CustomBuildTaskTerminal ( resolvedcompilerPath , definition ? definition . args : [ ] , definition ? definition . options : undefined )
194+ new CustomBuildTaskTerminal ( resolvedcompilerPath , resolvedDefinition . args , resolvedDefinition . options )
191195 ) , isCl ? '$msCompile' : '$gcc' ) ;
192196
193197 task . group = TaskGroup . Build ;
194- task . detail = detail ? detail : " compiler: " + resolvedcompilerPath ;
198+ task . detail = detail ? detail : localize ( "compiler_details" , " compiler:" ) + " " + resolvedcompilerPath ;
195199
196200 return task ;
197201 } ;
@@ -200,6 +204,9 @@ export class CppBuildTaskProvider implements TaskProvider {
200204 const rawJson : any = await this . getRawTasksJson ( ) ;
201205 const rawTasksJson : any = ( ! rawJson . tasks ) ? new Array ( ) : rawJson . tasks ;
202206 const buildTasksJson : CppBuildTask [ ] = rawTasksJson . map ( ( task : any ) => {
207+ if ( ! task . label ) {
208+ return null ;
209+ }
203210 const definition : CppBuildTaskDefinition = {
204211 type : task . type ,
205212 label : task . label ,
@@ -211,7 +218,7 @@ export class CppBuildTaskProvider implements TaskProvider {
211218 cppBuildTask . detail = task . detail ;
212219 return cppBuildTask ;
213220 } ) ;
214- return buildTasksJson ;
221+ return buildTasksJson . filter ( ( task : CppBuildTask ) => task !== null ) ;
215222 }
216223
217224 public async ensureBuildTaskExists ( taskLabel : string ) : Promise < void > {
@@ -252,7 +259,7 @@ export class CppBuildTaskProvider implements TaskProvider {
252259 ...selectedTask . definition ,
253260 problemMatcher : selectedTask . problemMatchers ,
254261 group : { kind : "build" , "isDefault" : true } ,
255- detail : "Generated task by Debugger"
262+ detail : localize ( "task_generated_by_debugger" , "Task generated by Debugger." )
256263 } ;
257264 rawTasksJson . tasks . push ( newTask ) ;
258265 }
@@ -333,7 +340,7 @@ class CustomBuildTaskTerminal implements Pseudoterminal {
333340 async open ( _initialDimensions : TerminalDimensions | undefined ) : Promise < void > {
334341 telemetry . logLanguageServerEvent ( "cppBuildTaskStarted" ) ;
335342 // At this point we can start using the terminal.
336- this . writeEmitter . fire ( ` Starting build...${ this . endOfLine } ` ) ;
343+ this . writeEmitter . fire ( localize ( "starting_build" , " Starting build..." ) + this . endOfLine ) ;
337344 await this . doBuild ( ) ;
338345 }
339346
@@ -343,16 +350,16 @@ class CustomBuildTaskTerminal implements Pseudoterminal {
343350
344351 private async doBuild ( ) : Promise < any > {
345352 // Do build.
346- let activeCommand : string = util . resolveVariables ( this . command , this . AdditionalEnvironment ) ;
353+ let activeCommand : string = util . resolveVariables ( this . command ) ;
347354 this . args . forEach ( value => {
348- let temp : string = util . resolveVariables ( value , this . AdditionalEnvironment ) ;
355+ let temp : string = util . resolveVariables ( value ) ;
349356 if ( temp && temp . includes ( " " ) ) {
350357 temp = "\"" + temp + "\"" ;
351358 }
352359 activeCommand = activeCommand + " " + temp ;
353360 } ) ;
354361 if ( this . options ?. cwd ) {
355- this . options . cwd = util . resolveVariables ( this . options . cwd , this . AdditionalEnvironment ) ;
362+ this . options . cwd = util . resolveVariables ( this . options . cwd ) ;
356363 }
357364
358365 const splitWriteEmitter = ( lines : string | Buffer ) => {
@@ -363,16 +370,34 @@ class CustomBuildTaskTerminal implements Pseudoterminal {
363370 try {
364371 const result : number = await new Promise < number > ( ( resolve , reject ) => {
365372 cp . exec ( activeCommand , this . options , ( _error , stdout , _stderr ) => {
373+ const dot : string = ( stdout || _stderr ) ? ":" : "." ;
366374 if ( _error ) {
367375 telemetry . logLanguageServerEvent ( "cppBuildTaskError" ) ;
368- const dot : string = ( stdout || _stderr ) ? ":" : "." ;
369- this . writeEmitter . fire ( `Build finished with error${ dot } ${ this . endOfLine } ` ) ;
370- splitWriteEmitter ( stdout ) ;
371- splitWriteEmitter ( _stderr ) ;
376+ this . writeEmitter . fire ( localize ( "build_finished_with_error" , "Build finished with errors(s)" ) + dot + this . endOfLine ) ;
377+ if ( stdout ) {
378+ splitWriteEmitter ( stdout ) ; // cl.exe
379+ } else if ( _stderr ) {
380+ splitWriteEmitter ( _stderr ) ; // gcc/clang
381+ } else {
382+ splitWriteEmitter ( _error . message ) ; // e.g. command executable not found
383+ }
372384 resolve ( - 1 ) ;
373- } else {
385+ return ;
386+ } else if ( _stderr && ! stdout ) { // gcc/clang
387+ telemetry . logLanguageServerEvent ( "cppBuildTaskWarnings" ) ;
388+ this . writeEmitter . fire ( localize ( "build_finished_with_warnings" , "Build finished with warning(s)" ) + dot + this . endOfLine ) ;
389+ splitWriteEmitter ( _stderr ) ;
390+ resolve ( 0 ) ;
391+ } else if ( stdout && stdout . includes ( "warning C" ) ) { // cl.exe
392+ telemetry . logLanguageServerEvent ( "cppBuildTaskWarnings" ) ;
393+ this . writeEmitter . fire ( localize ( "build_finished_with_warnings" , "Build finished with warning(s)" ) + dot + this . endOfLine ) ;
374394 splitWriteEmitter ( stdout ) ;
375- this . writeEmitter . fire ( `Build finished successfully.${ this . endOfLine } ` ) ;
395+ resolve ( 0 ) ;
396+ } else {
397+ if ( stdout ) {
398+ splitWriteEmitter ( stdout ) ; // cl.exe
399+ }
400+ this . writeEmitter . fire ( localize ( "build finished successfully" , "Build finished successfully." ) + this . endOfLine ) ;
376401 resolve ( 0 ) ;
377402 }
378403 } ) ;
@@ -382,23 +407,4 @@ class CustomBuildTaskTerminal implements Pseudoterminal {
382407 this . closeEmitter . fire ( - 1 ) ;
383408 }
384409 }
385-
386- private get AdditionalEnvironment ( ) : { [ key : string ] : string | string [ ] } | undefined {
387- const editor : TextEditor | undefined = window . activeTextEditor ;
388- if ( ! editor ) {
389- return undefined ;
390- }
391- const fileDir : WorkspaceFolder | undefined = workspace . getWorkspaceFolder ( editor . document . uri ) ;
392- if ( ! fileDir ) {
393- window . showErrorMessage ( 'This command is not yet available for single-file mode.' ) ;
394- return undefined ;
395- }
396- const file : string = editor . document . fileName ;
397- return {
398- "file" : file ,
399- "fileDirname" : path . parse ( file ) . dir ,
400- "fileBasenameNoExtension" : path . parse ( file ) . name ,
401- "workspaceFolder" : fileDir . uri . fsPath
402- } ;
403- }
404410}
0 commit comments