@@ -214,95 +214,91 @@ function clearCoverage() {
214214 * @param packageDirPath Absolute path of the package for which the coverage was calculated
215215 * @param dir Directory to execute go list in
216216 */
217- export function applyCodeCoverageToAllEditors ( coverProfilePath : string , dir ?: string ) : Promise < void > {
218- const v = new Promise < void > ( ( resolve , reject ) => {
219- try {
220- const showCounts = getGoConfig ( ) . get ( 'coverShowCounts' ) as boolean ;
221- const coveragePath = new Map < string , CoverageData > ( ) ; // <filename> from the cover profile to the coverage data.
222-
223- // Clear existing coverage files
224- clearCoverage ( ) ;
225-
226- // collect the packages named in the coverage file
227- const seenPaths = new Set < string > ( ) ;
228- // for now read synchronously and hope for no errors
229- const contents = fs . readFileSync ( coverProfilePath ) . toString ( ) ;
230- contents . split ( '\n' ) . forEach ( ( line ) => {
231- // go test coverageprofile generates output:
232- // filename:StartLine.StartColumn,EndLine.EndColumn Hits CoverCount
233- // where the filename is either the import path + '/' + base file name, or
234- // the actual file path (either absolute or starting with .)
235- // See https://golang.org/issues/40251.
236- //
237- // The first line will be like "mode: set" which we will ignore.
238- // TODO: port https://golang.org/cl/179377 for faster parsing.
239-
240- const parse = line . match ( / ^ ( \S + ) \: ( \d + ) \. ( \d + ) \, ( \d + ) \. ( \d + ) \s ( \d + ) \s ( \d + ) / ) ;
241- if ( ! parse ) {
242- return ;
243- }
217+ export async function applyCodeCoverageToAllEditors ( coverProfilePath : string , dir ?: string ) : Promise < void > {
218+ try {
219+ const showCounts = getGoConfig ( ) . get ( 'coverShowCounts' ) as boolean ;
220+ const coveragePath = new Map < string , CoverageData > ( ) ; // <filename> from the cover profile to the coverage data.
244221
245- let filename = parse [ 1 ] ;
246- if ( filename . startsWith ( '.' + path . sep ) ) {
247- // If it's a relative file path, convert it to an absolute path.
248- // From now on, we can assume that it's a real file name if it is
249- // an absolute path.
250- filename = path . resolve ( filename ) ;
251- }
252- // If this is not a real file name, that's package_path + file name,
253- // Record it in seenPaths for `go list` call to resolve package path ->
254- // directory mapping.
255- if ( ! path . isAbsolute ( filename ) ) {
256- const lastSlash = filename . lastIndexOf ( '/' ) ;
257- if ( lastSlash !== - 1 ) {
258- seenPaths . add ( filename . slice ( 0 , lastSlash ) ) ;
259- }
260- }
222+ // Clear existing coverage files
223+ clearCoverage ( ) ;
261224
262- // and fill in coveragePath
263- const coverage = coveragePath . get ( parse [ 1 ] ) || emptyCoverageData ( ) ;
264- // When line directive is used this information is artificial and
265- // the source code file can be non-existent or wrong (go.dev/issues/41222).
266- // There is no perfect way to guess whether the line/col in coverage profile
267- // is bogus. At least, we know that 0 or negative values are not true line/col.
268- const startLine = parseInt ( parse [ 2 ] , 10 ) ;
269- const startCol = parseInt ( parse [ 3 ] , 10 ) ;
270- const endLine = parseInt ( parse [ 4 ] , 10 ) ;
271- const endCol = parseInt ( parse [ 5 ] , 10 ) ;
272- if ( startLine < 1 || startCol < 1 || endLine < 1 || endCol < 1 ) {
273- return ;
274- }
275- const range = new vscode . Range (
276- // Convert lines and columns to 0-based
277- startLine - 1 ,
278- startCol - 1 ,
279- endLine - 1 ,
280- endCol - 1
281- ) ;
282-
283- const counts = parseInt ( parse [ 7 ] , 10 ) ;
284- // If is Covered (CoverCount > 0)
285- if ( counts > 0 ) {
286- coverage . coveredOptions . push ( ...elaborate ( range , counts , showCounts ) ) ;
287- } else {
288- coverage . uncoveredOptions . push ( ...elaborate ( range , counts , showCounts ) ) ;
225+ // collect the packages named in the coverage file
226+ const seenPaths = new Set < string > ( ) ;
227+ // Read coverage file asynchronously to avoid blocking the UI
228+ const contents = await fs . promises . readFile ( coverProfilePath , 'utf8' ) ;
229+ contents . split ( '\n' ) . forEach ( ( line ) => {
230+ // go test coverageprofile generates output:
231+ // filename:StartLine.StartColumn,EndLine.EndColumn Hits CoverCount
232+ // where the filename is either the import path + '/' + base file name, or
233+ // the actual file path (either absolute or starting with .)
234+ // See https://golang.org/issues/40251.
235+ //
236+ // The first line will be like "mode: set" which we will ignore.
237+ // TODO: port https://golang.org/cl/179377 for faster parsing.
238+
239+ const parse = line . match ( / ^ ( \S + ) \: ( \d + ) \. ( \d + ) \, ( \d + ) \. ( \d + ) \s ( \d + ) \s ( \d + ) / ) ;
240+ if ( ! parse ) {
241+ return ;
242+ }
243+
244+ let filename = parse [ 1 ] ;
245+ if ( filename . startsWith ( '.' + path . sep ) ) {
246+ // If it's a relative file path, convert it to an absolute path.
247+ // From now on, we can assume that it's a real file name if it is
248+ // an absolute path.
249+ filename = path . resolve ( filename ) ;
250+ }
251+ // If this is not a real file name, that's package_path + file name,
252+ // Record it in seenPaths for `go list` call to resolve package path ->
253+ // directory mapping.
254+ if ( ! path . isAbsolute ( filename ) ) {
255+ const lastSlash = filename . lastIndexOf ( '/' ) ;
256+ if ( lastSlash !== - 1 ) {
257+ seenPaths . add ( filename . slice ( 0 , lastSlash ) ) ;
289258 }
259+ }
290260
291- coveragePath . set ( filename , coverage ) ;
292- } ) ;
293-
294- getImportPathToFolder ( [ ...seenPaths ] , dir ) . then ( ( pathsToDirs ) => {
295- createCoverageData ( pathsToDirs , coveragePath ) ;
296- setDecorators ( ) ;
297- vscode . window . visibleTextEditors . forEach ( applyCodeCoverage ) ;
298- resolve ( ) ;
299- } ) ;
300- } catch ( e ) {
301- vscode . window . showInformationMessage ( ( e as any ) . msg ) ;
302- reject ( e ) ;
303- }
304- } ) ;
305- return v ;
261+ // and fill in coveragePath
262+ const coverage = coveragePath . get ( parse [ 1 ] ) || emptyCoverageData ( ) ;
263+ // When line directive is used this information is artificial and
264+ // the source code file can be non-existent or wrong (go.dev/issues/41222).
265+ // There is no perfect way to guess whether the line/col in coverage profile
266+ // is bogus. At least, we know that 0 or negative values are not true line/col.
267+ const startLine = parseInt ( parse [ 2 ] , 10 ) ;
268+ const startCol = parseInt ( parse [ 3 ] , 10 ) ;
269+ const endLine = parseInt ( parse [ 4 ] , 10 ) ;
270+ const endCol = parseInt ( parse [ 5 ] , 10 ) ;
271+ if ( startLine < 1 || startCol < 1 || endLine < 1 || endCol < 1 ) {
272+ return ;
273+ }
274+ const range = new vscode . Range (
275+ // Convert lines and columns to 0-based
276+ startLine - 1 ,
277+ startCol - 1 ,
278+ endLine - 1 ,
279+ endCol - 1
280+ ) ;
281+
282+ const counts = parseInt ( parse [ 7 ] , 10 ) ;
283+ // If is Covered (CoverCount > 0)
284+ if ( counts > 0 ) {
285+ coverage . coveredOptions . push ( ...elaborate ( range , counts , showCounts ) ) ;
286+ } else {
287+ coverage . uncoveredOptions . push ( ...elaborate ( range , counts , showCounts ) ) ;
288+ }
289+
290+ coveragePath . set ( filename , coverage ) ;
291+ } ) ;
292+
293+ const pathsToDirs = await getImportPathToFolder ( [ ...seenPaths ] , dir ) ;
294+ createCoverageData ( pathsToDirs , coveragePath ) ;
295+ setDecorators ( ) ;
296+ vscode . window . visibleTextEditors . forEach ( applyCodeCoverage ) ;
297+ } catch ( e ) {
298+ const errorMsg = ( e as any ) . msg || String ( e ) ;
299+ vscode . window . showInformationMessage ( errorMsg ) ;
300+ throw e ;
301+ }
306302}
307303
308304// add decorations to the range
@@ -356,7 +352,7 @@ function createCoverageData(pathsToDirs: Map<string, string>, coveragePath: Map<
356352 */
357353function setCoverageDataByFilePath ( filePath : string , data : CoverageData ) {
358354 if ( filePath . startsWith ( '_' ) ) {
359- filePath = filePath . substr ( 1 ) ;
355+ filePath = filePath . substring ( 1 ) ;
360356 }
361357 if ( process . platform === 'win32' ) {
362358 const parts = filePath . split ( '/' ) ;
0 commit comments