@@ -71,6 +71,7 @@ final class IncrementalCompilationTests: XCTestCase {
71
71
// "-v",
72
72
" -save-temps " ,
73
73
" -incremental " ,
74
+ " -no-color-diagnostics " ,
74
75
]
75
76
+ inputPathsAndContents. map { $0. 0 . pathString} . sorted ( )
76
77
}
@@ -336,8 +337,6 @@ extension IncrementalCompilationTests {
336
337
fileprivate enum RemovalTestOption : String , CaseIterable , Comparable , Hashable , CustomStringConvertible {
337
338
case
338
339
removeInputFromInvocation,
339
- removeSourceFile,
340
- removePreviouslyAddedInputFromOutputFileMap,
341
340
removeSwiftDepsFile,
342
341
restoreBadPriors
343
342
@@ -352,7 +351,7 @@ fileprivate enum RemovalTestOption: String, CaseIterable, Comparable, Hashable,
352
351
}
353
352
var mask : Int { 1 << intValue}
354
353
static let maxIntValue = allCases. map { $0. intValue} . max ( ) !
355
- static let maxCombinedValue = ( 1 << maxIntValue) - 1
354
+ static let maxCombinedValue = ( 1 << ( maxIntValue + 1 ) ) - 1
356
355
357
356
var description : String { rawValue }
358
357
}
@@ -379,7 +378,6 @@ extension IncrementalCompilationTests {
379
378
380
379
/// Someday, turn this test on and test all cases
381
380
func testRemovalInAllCases( ) throws {
382
- throw XCTSkip ( " unimplemented " )
383
381
try testRemoval ( includeFailingCombos: true )
384
382
}
385
383
@@ -400,26 +398,16 @@ extension IncrementalCompilationTests {
400
398
}
401
399
402
400
private func testRemoval( _ options: RemovalTestOptions ) throws {
403
- guard !options . isEmpty else { return }
404
- print ( " *** testRemoval \( options) *** " , to: & stderrStream) ; stderrStream. flush ( )
401
+ setUp ( ) // clear derived data, restore output file map
402
+ print ( " \n *** testRemoval \( options) *** " , to: & stderrStream) ; stderrStream. flush ( )
405
403
406
404
let newInput = " another "
407
405
let topLevelName = " nameInAnother "
408
406
try testAddingInput ( newInput: newInput, defining: topLevelName)
409
- if options. contains ( . removeSourceFile) {
410
- removeInput ( newInput)
411
- }
412
- if options. contains ( . removeSwiftDepsFile) {
413
- removeSwiftDeps ( newInput)
414
- }
415
- if options. contains ( . removePreviouslyAddedInputFromOutputFileMap) {
416
- // FACTOR
417
- OutputFileMapCreator . write ( module: module,
418
- inputPaths: inputPathsAndContents. map { $0. 0 } ,
419
- derivedData: derivedDataPath,
420
- to: OFM)
421
- }
422
- let includeInputInInvocation = !options. contains ( . removeInputFromInvocation)
407
+
408
+ let removeInputFromInvocation = options. contains ( . removeInputFromInvocation)
409
+ let removeSwiftDepsFile = options. contains ( . removeSwiftDepsFile)
410
+ let restoreBadPriors = options. contains ( . restoreBadPriors)
423
411
do {
424
412
let wrapperFn = options. contains ( . restoreBadPriors)
425
413
? preservingPriorsDo
@@ -428,14 +416,16 @@ extension IncrementalCompilationTests {
428
416
try self . checkNonincrementalAfterRemoving (
429
417
removedInput: newInput,
430
418
defining: topLevelName,
431
- includeInputInInvocation: includeInputInInvocation)
419
+ removeInputFromInvocation: removeInputFromInvocation,
420
+ removeSwiftDepsFile: removeSwiftDepsFile)
432
421
}
433
422
}
434
423
try checkRestorationOfIncrementalityAfterRemoval (
435
424
removedInput: newInput,
436
425
defining: topLevelName,
437
- includeInputInInvocation: includeInputInInvocation,
438
- afterRestoringBadPriors: options. contains ( . restoreBadPriors) )
426
+ removeInputFromInvocation: removeInputFromInvocation,
427
+ removeSwiftDepsFile: removeSwiftDepsFile,
428
+ afterRestoringBadPriors: restoreBadPriors)
439
429
}
440
430
}
441
431
@@ -700,25 +690,62 @@ extension IncrementalCompilationTests {
700
690
private func checkNonincrementalAfterRemoving(
701
691
removedInput: String ,
702
692
defining topLevelName: String ,
703
- includeInputInInvocation: Bool
693
+ removeInputFromInvocation: Bool ,
694
+ removeSwiftDepsFile: Bool
704
695
) throws {
705
- let extraArguments = includeInputInInvocation
706
- ? [ inputPath ( basename: removedInput) . pathString]
707
- : [ ]
708
- try doABuild (
709
- " after removal of \( removedInput) " ,
710
- checkDiagnostics: true ,
711
- extraArguments: extraArguments,
712
- expecting: [
696
+ let extraArguments = removeInputFromInvocation
697
+ ? [ ] : [ inputPath ( basename: removedInput) . pathString]
698
+
699
+ if removeSwiftDepsFile {
700
+ removeSwiftDeps ( removedInput)
701
+ }
702
+ let expectations : [ [ Diagnostic . Message ] ]
703
+ switch ( removeInputFromInvocation, removeSwiftDepsFile) {
704
+ case ( false , false ) :
705
+ expectations = [
706
+ . readGraphAndSkipAll( " main " , " other " , removedInput)
707
+ ]
708
+ case
709
+ ( true , false ) ,
710
+ ( true , true ) :
711
+ expectations = [
713
712
. remarks(
714
713
" Incremental compilation: Incremental compilation has been disabled, because the following inputs were used in the previous compilation but not in this one: \( removedInput) .swift " ) ,
715
714
. findingBatchingCompiling( " main " , " other " ) ,
716
715
. linking,
717
- ] ,
716
+ ]
717
+ case ( false , true ) :
718
+ expectations = [
719
+ . readGraph,
720
+ . enablingCrossModule,
721
+ . maySkip( " main " , " other " , removedInput) ,
722
+ . missing( removedInput) ,
723
+ . queuingInitial( removedInput) ,
724
+ . skipping( " main " , " other " ) ,
725
+ . findingBatchingCompiling( removedInput) ,
726
+ . schedulingPostCompileJobs,
727
+ . linking,
728
+ . skipped( " main " , " other " ) ,
729
+ ]
730
+ }
731
+
732
+ let driver = try doABuild (
733
+ " after removal of \( removedInput) " ,
734
+ checkDiagnostics: true ,
735
+ extraArguments: extraArguments,
736
+ expecting: expectations,
718
737
whenAutolinking: autolinkLifecycleExpectations)
719
- . verifyNoGraph ( )
720
738
721
- verifyNoPriors ( )
739
+ if removeInputFromInvocation {
740
+ driver. verifyNoGraph ( )
741
+ verifyNoPriors ( )
742
+ }
743
+ else {
744
+ let graph = try driver. moduleDependencyGraph ( )
745
+ graph. verifyGraph ( )
746
+ XCTAssert ( graph. contains ( sourceBasenameWithoutExt: removedInput) )
747
+ XCTAssert ( graph. contains ( name: topLevelName) )
748
+ }
722
749
}
723
750
724
751
/// Ensure that incremental builds happen after a removal.
@@ -730,34 +757,68 @@ extension IncrementalCompilationTests {
730
757
private func checkRestorationOfIncrementalityAfterRemoval(
731
758
removedInput: String ,
732
759
defining topLevelName: String ,
733
- includeInputInInvocation: Bool ,
760
+ removeInputFromInvocation: Bool ,
761
+ removeSwiftDepsFile: Bool ,
734
762
afterRestoringBadPriors: Bool
735
763
) throws -> ModuleDependencyGraph {
736
- let extraArguments = includeInputInInvocation
737
- ? [ inputPath ( basename: removedInput) . pathString]
738
- : [ ]
739
- let expectations : [ [ Diagnostic . Message ] ] = afterRestoringBadPriors
740
- ? [
741
- . readGraph,
742
- . enablingCrossModule,
743
- . skippingAll( " main " , " other " ) ,
744
- ]
745
- : [
746
- . createdGraphFromSwiftdeps,
747
- . enablingCrossModule,
748
- . skippingAll( " main " , " other " ) ,
749
- ]
764
+ let extraArguments = removeInputFromInvocation
765
+ ? [ ] : [ inputPath ( basename: removedInput) . pathString]
766
+ let inputs = [ " main " , " other " ] + ( removeInputFromInvocation ? [ ] : [ removedInput] )
767
+ let expectations : [ [ Diagnostic . Message ] ]
768
+ switch ( removeInputFromInvocation, removeSwiftDepsFile, afterRestoringBadPriors) {
769
+ case
770
+ ( false , false , false ) ,
771
+ ( false , true , false ) ,
772
+ ( false , false , true ) ,
773
+ ( true , false , true ) ,
774
+ ( true , true , true ) ,
775
+ ( false , true , true ) :
776
+ expectations = [
777
+ . readGraphAndSkipAll( inputs)
778
+ ]
779
+ case
780
+ ( true , false , false ) ,
781
+ ( true , true , false ) :
782
+ expectations = [
783
+ . createdGraphFromSwiftdeps,
784
+ . enablingCrossModule,
785
+ . skippingAll( inputs) ,
786
+ ]
787
+ }
788
+
750
789
let graph = try doABuild (
751
- " after after removal of \( removedInput) " ,
790
+ " restoring incrementality after removal of \( removedInput) " ,
752
791
checkDiagnostics: true ,
753
792
extraArguments: extraArguments,
754
793
expecting: expectations,
755
794
whenAutolinking: autolinkLifecycleExpectations)
756
795
. moduleDependencyGraph ( )
757
796
758
797
graph. verifyGraph ( )
759
- graph. ensureOmits ( sourceBasenameWithoutExt: removedInput)
760
- graph. ensureOmits ( name: topLevelName)
798
+ if removeInputFromInvocation {
799
+ if afterRestoringBadPriors {
800
+ // FIXME: Fix the driver
801
+ // If you incrementally compile with a.swift and b.swift,
802
+ // at the end, the driver saves a serialized `ModuleDependencyGraph`
803
+ // contains nodes for declarations defined in both files.
804
+ // If you then later remove b.swift and recompile, the driver will
805
+ // see that a file was removed (via comparisons with the saved `BuildRecord`
806
+ // and will delete the saved priors. However, if for some reason the
807
+ // saved priors are not deleted, the driver will read saved priors
808
+ // containing entries for the deleted file. This test simulates that
809
+ // condition by restoring the deleted priors. The driver ought to be fixed
810
+ // to cull any entries for removed files from the deserialized priors.
811
+ print ( " *** WARNING: skipping checks, driver fails to cleaned out the graph *** " ,
812
+ to: & stderrStream) ; stderrStream. flush ( )
813
+ return graph
814
+ }
815
+ graph. ensureOmits ( sourceBasenameWithoutExt: removedInput)
816
+ graph. ensureOmits ( name: topLevelName)
817
+ }
818
+ else {
819
+ XCTAssert ( graph. contains ( sourceBasenameWithoutExt: removedInput) )
820
+ XCTAssert ( graph. contains ( name: topLevelName) )
821
+ }
761
822
762
823
return graph
763
824
}
@@ -896,12 +957,14 @@ fileprivate extension ModuleDependencyGraph {
896
957
allNodes. contains { $0. contains ( name: target) }
897
958
}
898
959
func ensureOmits( sourceBasenameWithoutExt target: String ) {
960
+ // Written this way to show the faulty node when the assertion fails
899
961
nodeFinder. forEachNode { node in
900
962
XCTAssertFalse ( node. contains ( sourceBasenameWithoutExt: target) ,
901
963
" graph should omit source: \( target) " )
902
964
}
903
965
}
904
966
func ensureOmits( name: String ) {
967
+ // Written this way to show the faulty node when the assertion fails
905
968
nodeFinder. forEachNode { node in
906
969
XCTAssertFalse ( node. contains ( name: name) ,
907
970
" graph should omit decl named: \( name) " )
@@ -1096,11 +1159,24 @@ fileprivate extension Array where Element == Diagnostic.Message {
1096
1159
static func skipped( _ inputs: String ... ) -> Self {
1097
1160
skipped ( inputs)
1098
1161
}
1099
- static func skippingAll( _ inputs: String ... ) -> Self {
1162
+ static func skippingAll( _ inputs: [ String ] ) -> Self {
1100
1163
[
1101
1164
maySkip ( inputs) , skipping ( inputs) , skippingLinking, skipped ( inputs)
1102
1165
] . flatMap { $0}
1103
1166
}
1167
+ static func skippingAll( _ inputs: String ... ) -> Self {
1168
+ skippingAll ( inputs)
1169
+ }
1170
+ static func readGraphAndSkipAll( _ inputs: [ String ] ) -> Self {
1171
+ [
1172
+ readGraph,
1173
+ enablingCrossModule,
1174
+ skippingAll ( inputs)
1175
+ ] . flatMap { $0}
1176
+ }
1177
+ static func readGraphAndSkipAll( _ inputs: String ... ) -> Self {
1178
+ readGraphAndSkipAll ( inputs)
1179
+ }
1104
1180
1105
1181
// MARK: - batching
1106
1182
static func addingToBatch( _ inputs: [ String ] , _ b: Int ) -> Self {
0 commit comments