@@ -16,17 +16,17 @@ namespace ts.tscWatch {
1616 expectedIncrementalEmit ?: ReadonlyArray < File > ;
1717 expectedIncrementalErrors ?: ReadonlyArray < string > ;
1818 }
19- function verifyIncrementalWatchEmit ( input : VerifyIncrementalWatchEmitInput ) {
19+ function verifyIncrementalWatchEmit ( input : ( ) => VerifyIncrementalWatchEmitInput ) {
2020 it ( "with tsc --w" , ( ) => {
2121 verifyIncrementalWatchEmitWorker ( {
22- input,
22+ input : input ( ) ,
2323 emitAndReportErrors : createWatchOfConfigFile ,
2424 verifyErrors : checkOutputErrorsInitial
2525 } ) ;
2626 } ) ;
2727 it ( "with tsc" , ( ) => {
2828 verifyIncrementalWatchEmitWorker ( {
29- input,
29+ input : input ( ) ,
3030 emitAndReportErrors : incrementalBuild ,
3131 verifyErrors : checkNormalBuildErrors
3232 } ) ;
@@ -122,15 +122,15 @@ namespace ts.tscWatch {
122122
123123 function checkFileEmit ( actual : Map < string > , expected : ReadonlyArray < File > ) {
124124 assert . equal ( actual . size , expected . length , `Actual: ${ JSON . stringify ( arrayFrom ( actual . entries ( ) ) , /*replacer*/ undefined , " " ) } \nExpected: ${ JSON . stringify ( expected , /*replacer*/ undefined , " " ) } ` ) ;
125- expected . forEach ( file => {
125+ for ( const file of expected ) {
126126 let expectedContent = file . content ;
127127 let actualContent = actual . get ( file . path ) ;
128128 if ( isBuildInfoFile ( file . path ) ) {
129129 actualContent = actualContent && sanitizeBuildInfo ( actualContent ) ;
130130 expectedContent = sanitizeBuildInfo ( expectedContent ) ;
131131 }
132132 assert . equal ( actualContent , expectedContent , `Emit for ${ file . path } ` ) ;
133- } ) ;
133+ }
134134 }
135135
136136 const libFileInfo : BuilderState . FileInfo = {
@@ -170,7 +170,7 @@ namespace ts.tscWatch {
170170 describe ( "own file emit without errors" , ( ) => {
171171 function verify ( optionsToExtend ?: CompilerOptions , expectedBuildinfoOptions ?: CompilerOptions ) {
172172 const modifiedFile2Content = file2 . content . replace ( "y" , "z" ) . replace ( "20" , "10" ) ;
173- verifyIncrementalWatchEmit ( {
173+ verifyIncrementalWatchEmit ( ( ) => ( {
174174 files : [ libFile , file1 , file2 , configFile ] ,
175175 optionsToExtend,
176176 expectedInitialEmit : [
@@ -226,7 +226,7 @@ namespace ts.tscWatch {
226226 }
227227 ] ,
228228 expectedIncrementalErrors : emptyArray ,
229- } ) ;
229+ } ) ) ;
230230 }
231231 verify ( ) ;
232232 describe ( "with commandline parameters that are not relative" , ( ) => {
@@ -259,7 +259,7 @@ namespace ts.tscWatch {
259259 "file2.ts(1,7): error TS2322: Type '20' is not assignable to type 'string'.\n"
260260 ] ;
261261 const modifiedFile1Content = file1 . content . replace ( "x" , "z" ) ;
262- verifyIncrementalWatchEmit ( {
262+ verifyIncrementalWatchEmit ( ( ) => ( {
263263 files : [ libFile , file1 , fileModified , configFile ] ,
264264 expectedInitialEmit : [
265265 file1Js ,
@@ -320,7 +320,7 @@ namespace ts.tscWatch {
320320 }
321321 ] ,
322322 expectedIncrementalErrors : file2Errors ,
323- } ) ;
323+ } ) ) ;
324324 } ) ;
325325
326326 describe ( "with --out" , ( ) => {
@@ -332,7 +332,7 @@ namespace ts.tscWatch {
332332 path : `${ project } /out.js` ,
333333 content : "var x = 10;\nvar y = 20;\n"
334334 } ;
335- verifyIncrementalWatchEmit ( {
335+ verifyIncrementalWatchEmit ( ( ) => ( {
336336 files : [ libFile , file1 , file2 , config ] ,
337337 expectedInitialEmit : [
338338 outFile ,
@@ -353,7 +353,7 @@ namespace ts.tscWatch {
353353 }
354354 ] ,
355355 expectedInitialErrors : emptyArray
356- } ) ;
356+ } ) ) ;
357357 } ) ;
358358
359359 } ) ;
@@ -397,7 +397,7 @@ namespace ts.tscWatch {
397397
398398 describe ( "own file emit without errors" , ( ) => {
399399 const modifiedFile2Content = file2 . content . replace ( "y" , "z" ) . replace ( "20" , "10" ) ;
400- verifyIncrementalWatchEmit ( {
400+ verifyIncrementalWatchEmit ( ( ) => ( {
401401 files : [ libFile , file1 , file2 , config ] ,
402402 expectedInitialEmit : [
403403 file1Js ,
@@ -451,7 +451,7 @@ namespace ts.tscWatch {
451451 }
452452 ] ,
453453 expectedIncrementalErrors : emptyArray ,
454- } ) ;
454+ } ) ) ;
455455 } ) ;
456456
457457 describe ( "own file emit with errors" , ( ) => {
@@ -479,7 +479,7 @@ namespace ts.tscWatch {
479479 "file2.ts(1,14): error TS2322: Type '20' is not assignable to type 'string'.\n"
480480 ] ;
481481 const modifiedFile1Content = file1 . content . replace ( "x = 10" , "z = 10" ) ;
482- verifyIncrementalWatchEmit ( {
482+ verifyIncrementalWatchEmit ( ( ) => ( {
483483 files : [ libFile , file1 , fileModified , config ] ,
484484 expectedInitialEmit : [
485485 file1Js ,
@@ -541,7 +541,7 @@ namespace ts.tscWatch {
541541 }
542542 ] ,
543543 expectedIncrementalErrors : file2Errors ,
544- } ) ;
544+ } ) ) ;
545545
546546 it ( "verify that state is read correctly" , ( ) => {
547547 const system = createWatchedSystem ( [ libFile , file1 , fileModified , config ] , { currentDirectory : project } ) ;
@@ -604,7 +604,7 @@ namespace ts.tscWatch {
604604});
605605` ;
606606 }
607- verifyIncrementalWatchEmit ( {
607+ verifyIncrementalWatchEmit ( ( ) => ( {
608608 files : [ libFile , file1 , file2 , config ] ,
609609 expectedInitialEmit : [
610610 outFile ,
@@ -625,7 +625,140 @@ namespace ts.tscWatch {
625625 }
626626 ] ,
627627 expectedInitialErrors : emptyArray
628- } ) ;
628+ } ) ) ;
629+ } ) ;
630+ } ) ;
631+
632+ describe ( "incremental with circular references" , ( ) => {
633+ function getFileInfo ( content : string ) : BuilderState . FileInfo {
634+ const signature = Harness . mockHash ( content ) ;
635+ return { version : signature , signature } ;
636+ }
637+ const config : File = {
638+ path : configFile . path ,
639+ content : JSON . stringify ( {
640+ compilerOptions : {
641+ incremental : true ,
642+ target : "es5" ,
643+ module : "commonjs" ,
644+ declaration : true ,
645+ emitDeclarationOnly : true
646+ }
647+ } )
648+ } ;
649+ const aTs : File = {
650+ path : `${ project } /a.ts` ,
651+ content : `import { B } from "./b";
652+ export interface A {
653+ b: B;
654+ }
655+ `
656+ } ;
657+ const bTs : File = {
658+ path : `${ project } /b.ts` ,
659+ content : `import { C } from "./c";
660+ export interface B {
661+ b: C;
662+ }
663+ `
664+ } ;
665+ const cTs : File = {
666+ path : `${ project } /c.ts` ,
667+ content : `import { A } from "./a";
668+ export interface C {
669+ a: A;
670+ }
671+ `
672+ } ;
673+ const indexTs : File = {
674+ path : `${ project } /index.ts` ,
675+ content : `export { A } from "./a";
676+ export { B } from "./b";
677+ export { C } from "./c";
678+ `
679+ } ;
680+
681+ verifyIncrementalWatchEmit ( ( ) => {
682+ const referencedMap : MapLike < string [ ] > = {
683+ "./a.ts" : [ "./b.ts" ] ,
684+ "./b.ts" : [ "./c.ts" ] ,
685+ "./c.ts" : [ "./a.ts" ] ,
686+ "./index.ts" : [ "./a.ts" , "./b.ts" , "./c.ts" ] ,
687+ } ;
688+ const initialProgram : ProgramBuildInfo = {
689+ fileInfos : {
690+ [ libFilePath ] : libFileInfo ,
691+ "./c.ts" : getFileInfo ( cTs . content ) ,
692+ "./b.ts" : getFileInfo ( bTs . content ) ,
693+ "./a.ts" : getFileInfo ( aTs . content ) ,
694+ "./index.ts" : getFileInfo ( indexTs . content )
695+ } ,
696+ options : {
697+ incremental : true ,
698+ target : ScriptTarget . ES5 ,
699+ module : ModuleKind . CommonJS ,
700+ declaration : true ,
701+ emitDeclarationOnly : true ,
702+ configFilePath : "./tsconfig.json"
703+ } ,
704+ referencedMap,
705+ exportedModulesMap : referencedMap ,
706+ semanticDiagnosticsPerFile : [
707+ libFilePath ,
708+ "./a.ts" ,
709+ "./b.ts" ,
710+ "./c.ts" ,
711+ "./index.ts" ,
712+ ]
713+ } ;
714+ const { fileInfos, ...rest } = initialProgram ;
715+ const expectedADts : File = { path : `${ project } /a.d.ts` , content : aTs . content } ;
716+ const expectedBDts : File = { path : `${ project } /b.d.ts` , content : bTs . content } ;
717+ const expectedCDts : File = { path : `${ project } /c.d.ts` , content : cTs . content } ;
718+ const expectedIndexDts : File = { path : `${ project } /index.d.ts` , content : indexTs . content } ;
719+ const modifiedATsContent = aTs . content . replace ( "b: B;" , `b: B;
720+ foo: any;` ) ;
721+ return {
722+ files : [ libFile , aTs , bTs , cTs , indexTs , config ] ,
723+ expectedInitialEmit : [
724+ expectedADts ,
725+ expectedBDts ,
726+ expectedCDts ,
727+ expectedIndexDts ,
728+ {
729+ path : `${ project } /tsconfig.tsbuildinfo` ,
730+ content : getBuildInfoText ( {
731+ program : initialProgram ,
732+ version
733+ } )
734+ }
735+ ] ,
736+ expectedInitialErrors : emptyArray ,
737+ modifyFs : host => host . writeFile ( aTs . path , modifiedATsContent ) ,
738+ expectedIncrementalEmit : [
739+ { path : expectedADts . path , content : modifiedATsContent } ,
740+ expectedBDts ,
741+ expectedCDts ,
742+ expectedIndexDts ,
743+ {
744+ path : `${ project } /tsconfig.tsbuildinfo` ,
745+ content : getBuildInfoText ( {
746+ program : {
747+ fileInfos : {
748+ [ libFilePath ] : libFileInfo ,
749+ "./c.ts" : getFileInfo ( cTs . content ) ,
750+ "./b.ts" : getFileInfo ( bTs . content ) ,
751+ "./a.ts" : getFileInfo ( modifiedATsContent ) ,
752+ "./index.ts" : getFileInfo ( indexTs . content )
753+ } ,
754+ ...rest
755+ } ,
756+ version
757+ } )
758+ }
759+ ] ,
760+ expectedIncrementalErrors : emptyArray
761+ } ;
629762 } ) ;
630763 } ) ;
631764 } ) ;
0 commit comments