@@ -405,13 +405,105 @@ namespace ts {
405
405
*/
406
406
export function parseConfigFileTextToJson ( fileName : string , jsonText : string ) : { config ?: any ; error ?: Diagnostic } {
407
407
try {
408
- return { config : / \S / . test ( jsonText ) ? JSON . parse ( jsonText ) : { } } ;
408
+ let jsonTextWithoutComments = removeComments ( jsonText ) ;
409
+ return { config : / \S / . test ( jsonTextWithoutComments ) ? JSON . parse ( jsonTextWithoutComments ) : { } } ;
409
410
}
410
411
catch ( e ) {
411
412
return { error : createCompilerDiagnostic ( Diagnostics . Failed_to_parse_file_0_Colon_1 , fileName , e . message ) } ;
412
413
}
413
414
}
414
415
416
+
417
+ /**
418
+ * Remove the comments from a json like text.
419
+ * Comments can be single line comments (starting with # or //) or multiline comments using / * * /
420
+ *
421
+ * This method replace comment content by whitespace rather than completely remove them to keep positions in json parsing error reporting accurate.
422
+ */
423
+ function removeComments ( jsonText : string ) : string {
424
+ let result = "" ;
425
+ let processingString = false ;
426
+ let processingSingleLineComment = false ;
427
+ let processingMultiLineComment = false ;
428
+ for ( let i = 0 ; i < jsonText . length ; i ++ ) {
429
+ let currentChar = jsonText . charAt ( i ) ;
430
+ let nextChar = ( i + 1 < jsonText . length ) ? jsonText . charAt ( i + 1 ) : undefined ;
431
+ if ( processingString ) {
432
+ if ( currentChar === "\\"
433
+ && nextChar === "\"" ) {
434
+ // Escaped quote consume the 2 characters
435
+ result += currentChar ;
436
+ result += nextChar ;
437
+ i += 1 ;
438
+ }
439
+ else if ( currentChar === "\"" ) {
440
+ // End of string
441
+ result += currentChar ;
442
+ processingString = false ;
443
+ }
444
+ else {
445
+ // String content
446
+ result += currentChar ;
447
+ }
448
+ }
449
+ else if ( processingSingleLineComment ) {
450
+ if ( currentChar === "\n" ) {
451
+ // End of single line comment
452
+ processingSingleLineComment = false ;
453
+ // Keep the line breaks to keep line numbers aligned
454
+ result += currentChar ;
455
+ }
456
+ else {
457
+ // replace comment content by whitespaces
458
+ result += " " ;
459
+ }
460
+ }
461
+ else if ( processingMultiLineComment ) {
462
+ if ( currentChar === "*" && nextChar === "/" ) {
463
+ // End of comment
464
+ result += " " ;
465
+ i += 1 ;
466
+ processingMultiLineComment = false ;
467
+ }
468
+ else if ( currentChar === "\n" ) {
469
+ // Keep the line breaks to Keep line aligned
470
+ result += currentChar ;
471
+ }
472
+ else {
473
+ // replace comment content by whitespaces
474
+ result += " " ;
475
+ }
476
+ }
477
+ else if ( currentChar === "\"" ) {
478
+ // String start
479
+ result += currentChar ;
480
+ processingString = true ;
481
+ }
482
+ else if ( currentChar === "#" ) {
483
+ // Start of # comment
484
+ result += " " ;
485
+ processingSingleLineComment = true ;
486
+ }
487
+ else if ( currentChar === "/" && nextChar === "/" ) {
488
+ // Start of // comment
489
+ result += " " ;
490
+ i += 1 ;
491
+ processingSingleLineComment = true ;
492
+ }
493
+ else if ( currentChar === "/" && nextChar === "*" ) {
494
+ // Start of /**/ comment
495
+ result += " " ;
496
+ i += 1 ;
497
+ processingMultiLineComment = true ;
498
+ }
499
+ else {
500
+ // Keep other characters
501
+ result += currentChar ;
502
+ }
503
+ }
504
+ return result ;
505
+ }
506
+
415
507
/**
416
508
* Parse the contents of a config file (tsconfig.json).
417
509
* @param json The contents of the config file to parse
0 commit comments