swift-api-digester: teach the tool to directly compare two module interfaces

We used to use a Json format to capture the ABI/API detail of Swift modules to
walk-around module compatibility issues across different compiler versions. Since
Swift module now is in stable format, we can compare two swiftinterface files
directly without dumping the content into Json format.
This commit is contained in:
Xi Ge
2019-05-31 18:52:12 -07:00
parent c9660106a7
commit d405fcd8ec
11 changed files with 233 additions and 175 deletions

View File

@@ -1,107 +1,107 @@
/* Generic Signature Changes */
cake1: Func P1.P1Constraint() has generic signature change from <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2> to <τ_0_0 where τ_0_0 : P1>
cake1: Protocol P3 has generic signature change from <τ_0_0 : cake.P1, τ_0_0 : cake.P2> to <τ_0_0 : cake.P1, τ_0_0 : cake.P4>
cake: Func P1.P1Constraint() has generic signature change from <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2> to <τ_0_0 where τ_0_0 : P1>
cake: Protocol P3 has generic signature change from <τ_0_0 : cake.P1, τ_0_0 : cake.P2> to <τ_0_0 : cake.P1, τ_0_0 : cake.P4>
/* RawRepresentable Changes */
/* Removed Decls */
Swift: Extension Int has been removed
cake1: Accessor GlobalVarChangedToLet.Set() has been removed
cake1: Accessor RemoveSetters.Value.Set() has been removed
cake1: AssociatedType RequiementChanges.removedType has been removed
cake1: Class C3 has been removed
cake1: Constructor Somestruct2.init(_:) has been removed
cake1: Func C4.foo() has been removed
cake1: Func RequiementChanges.removedFunc() has been removed
cake1: Subscript RemoveSetters.subscript(_:) has removed its setter
cake1: Var GlobalVarChangedToLet has removed its setter
cake1: Var RemoveSetters.Value has removed its setter
cake1: Var RequiementChanges.removedVar has been removed
cake: Accessor GlobalVarChangedToLet.Set() has been removed
cake: Accessor RemoveSetters.Value.Set() has been removed
cake: AssociatedType RequiementChanges.removedType has been removed
cake: Class C3 has been removed
cake: Constructor Somestruct2.init(_:) has been removed
cake: Func C4.foo() has been removed
cake: Func RequiementChanges.removedFunc() has been removed
cake: Subscript RemoveSetters.subscript(_:) has removed its setter
cake: Var GlobalVarChangedToLet has removed its setter
cake: Var RemoveSetters.Value has removed its setter
cake: Var RequiementChanges.removedVar has been removed
/* Moved Decls */
cake1: Class ClassToStruct has been changed to a Struct
cake1: InfixOperator ..*.. has been changed to a PrefixOperator
cake1: Protocol ProtocolToEnum has been changed to a Enum
cake: Class ClassToStruct has been changed to a Struct
cake: InfixOperator ..*.. has been changed to a PrefixOperator
cake: Protocol ProtocolToEnum has been changed to a Enum
/* Renamed Decls */
cake1: Func S1.foo5(x:y:) has been renamed to Func foo5(x:y:z:)
cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
cake: Func S1.foo5(x:y:) has been renamed to Func foo5(x:y:z:)
cake: Struct Somestruct2 has been renamed to Struct NSSomestruct2
/* Type Changes */
cake1: AssociatedType AssociatedTypePro.T3 has default type change from C1 to C6
cake1: Class TChangesFromIntToString has type witness type for AssociatedTypesProtocol.T changing from Int to String
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
cake1: Func C7.foo(_:_:) has removed default argument from parameter 0
cake1: Func C7.foo(_:_:) has removed default argument from parameter 1
cake1: Func EscapingFunctionType.addedEscaping(_:) has added @escaping in parameter 0
cake1: Func EscapingFunctionType.removedEscaping(_:) has removed @escaping in parameter 0
cake1: Func Somestruct2.foo1(_:) has parameter 0 type change from C3 to C1
cake1: Func ownershipChange(_:_:) has parameter 0 changing from InOut to Default
cake1: Func ownershipChange(_:_:) has parameter 1 changing from Shared to Owned
cake: AssociatedType AssociatedTypePro.T3 has default type change from C1 to C6
cake: Class TChangesFromIntToString has type witness type for AssociatedTypesProtocol.T changing from Int to String
cake: Constructor S1.init(_:) has parameter 0 type change from Int to Double
cake: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
cake: Func C7.foo(_:_:) has removed default argument from parameter 0
cake: Func C7.foo(_:_:) has removed default argument from parameter 1
cake: Func EscapingFunctionType.addedEscaping(_:) has added @escaping in parameter 0
cake: Func EscapingFunctionType.removedEscaping(_:) has removed @escaping in parameter 0
cake: Func Somestruct2.foo1(_:) has parameter 0 type change from C3 to C1
cake: Func ownershipChange(_:_:) has parameter 0 changing from InOut to Default
cake: Func ownershipChange(_:_:) has parameter 1 changing from Shared to Owned
/* Decl Attribute changes */
cake1: Class C5 is now without @objc
cake1: Enum IceKind is now without @frozen
cake1: Func C1.foo1() is now not static
cake1: Func C5.dy_foo() is now with dynamic
cake1: Func FinalFuncContainer.NewFinalFunc() is now with final
cake1: Func FinalFuncContainer.NoLongerFinalFunc() is now without final
cake1: Func HasMutatingMethodClone.foo() has self access kind changing from Mutating to NonMutating
cake1: Func S1.foo1() has self access kind changing from NonMutating to Mutating
cake1: Func S1.foo3() is now static
cake1: Func _NoResilientClass.NoLongerFinalFunc() is now without final
cake1: Struct C6 is now with @frozen
cake1: Var C1.CIIns1 changes from weak to strong
cake1: Var C1.CIIns2 changes from strong to weak
cake1: Var GlobalLetChangedToVar changes from let to var
cake1: Var GlobalVarChangedToLet changes from var to let
cake2: Accessor GlobalLetChangedToVar.Set() is a new API without @available attribute
cake2: Accessor fixedLayoutStruct2.BecomeFixedBinaryOrder.Set() is a new API without @available attribute
cake2: AssociatedType RequiementChanges.addedTypeWithDefault is a new API without @available attribute
cake2: AssociatedType RequiementChanges.addedTypeWithoutDefault is a new API without @available attribute
cake2: Class C0 is a new API without @available attribute
cake2: Class C8 is a new API without @available attribute
cake2: Constructor C1.init(_:) is a new API without @available attribute
cake2: EnumElement FrozenKind.AddedCase is a new API without @available attribute
cake2: Func RequiementChanges.addedFunc() is a new API without @available attribute
cake2: Func fixedLayoutStruct.OKChange() is a new API without @available attribute
cake2: Protocol P4 is a new API without @available attribute
cake2: Var RequiementChanges.addedVar is a new API without @available attribute
cake2: Var fixedLayoutStruct.$__lazy_storage_$_lazy_d is a new API without @available attribute
cake2: Var fixedLayoutStruct.c is a new API without @available attribute
cake: Accessor GlobalLetChangedToVar.Set() is a new API without @available attribute
cake: Accessor fixedLayoutStruct2.BecomeFixedBinaryOrder.Set() is a new API without @available attribute
cake: AssociatedType RequiementChanges.addedTypeWithDefault is a new API without @available attribute
cake: AssociatedType RequiementChanges.addedTypeWithoutDefault is a new API without @available attribute
cake: Class C0 is a new API without @available attribute
cake: Class C5 is now without @objc
cake: Class C8 is a new API without @available attribute
cake: Constructor C1.init(_:) is a new API without @available attribute
cake: Enum IceKind is now without @frozen
cake: EnumElement FrozenKind.AddedCase is a new API without @available attribute
cake: Func C1.foo1() is now not static
cake: Func C5.dy_foo() is now with dynamic
cake: Func FinalFuncContainer.NewFinalFunc() is now with final
cake: Func FinalFuncContainer.NoLongerFinalFunc() is now without final
cake: Func HasMutatingMethodClone.foo() has self access kind changing from Mutating to NonMutating
cake: Func RequiementChanges.addedFunc() is a new API without @available attribute
cake: Func S1.foo1() has self access kind changing from NonMutating to Mutating
cake: Func S1.foo3() is now static
cake: Func _NoResilientClass.NoLongerFinalFunc() is now without final
cake: Func fixedLayoutStruct.OKChange() is a new API without @available attribute
cake: Protocol P4 is a new API without @available attribute
cake: Struct C6 is now with @frozen
cake: Var C1.CIIns1 changes from weak to strong
cake: Var C1.CIIns2 changes from strong to weak
cake: Var GlobalLetChangedToVar changes from let to var
cake: Var GlobalVarChangedToLet changes from var to let
cake: Var RequiementChanges.addedVar is a new API without @available attribute
cake: Var fixedLayoutStruct.$__lazy_storage_$_lazy_d is a new API without @available attribute
cake: Var fixedLayoutStruct.c is a new API without @available attribute
/* Fixed-layout Type changes */
cake1: EnumElement FrozenKind.Fixed in a non-resilient type changes position from 1 to 2
cake1: EnumElement FrozenKind.Rigid in a non-resilient type changes position from 2 to 1
cake1: Var fixedLayoutStruct.a in a non-resilient type changes position from 1 to 0
cake1: Var fixedLayoutStruct.b in a non-resilient type changes position from 0 to 1
cake1: Var fixedLayoutStruct2.BecomeFixedBinaryOrder is now a stored property
cake1: Var fixedLayoutStruct2.NoLongerWithFixedBinaryOrder is no longer a stored property
cake2: EnumElement FrozenKind.AddedCase is added to a non-resilient type
cake2: Var fixedLayoutStruct.$__lazy_storage_$_lazy_d is added to a non-resilient type
cake2: Var fixedLayoutStruct.c is added to a non-resilient type
/* Fixed-layout Type Changes */
cake: EnumElement FrozenKind.AddedCase is added to a non-resilient type
cake: EnumElement FrozenKind.Fixed in a non-resilient type changes position from 1 to 2
cake: EnumElement FrozenKind.Rigid in a non-resilient type changes position from 2 to 1
cake: Var fixedLayoutStruct.$__lazy_storage_$_lazy_d is added to a non-resilient type
cake: Var fixedLayoutStruct.a in a non-resilient type changes position from 1 to 0
cake: Var fixedLayoutStruct.b in a non-resilient type changes position from 0 to 1
cake: Var fixedLayoutStruct.c is added to a non-resilient type
cake: Var fixedLayoutStruct2.BecomeFixedBinaryOrder is now a stored property
cake: Var fixedLayoutStruct2.NoLongerWithFixedBinaryOrder is no longer a stored property
/* Conformance changes */
cake1: Func ObjCProtocol.addOptional() is now an optional requirement
cake1: Func ObjCProtocol.removeOptional() is no longer an optional requirement
cake1: Protocol P3 has removed inherited protocol P2
cake1: Struct fixedLayoutStruct has removed conformance to P1
cake2: Class C7 has added a conformance to an existing protocol P1
cake2: Class SuperClassChange has added a conformance to an existing protocol P1
cake2: Protocol P3 has added inherited protocol P4
cake2: Struct fixedLayoutStruct has added a conformance to an existing protocol P2
/* Protocol Conformance Change */
cake: Class C7 has added a conformance to an existing protocol P1
cake: Class SuperClassChange has added a conformance to an existing protocol P1
cake: Func ObjCProtocol.addOptional() is now an optional requirement
cake: Func ObjCProtocol.removeOptional() is no longer an optional requirement
cake: Protocol P3 has added inherited protocol P4
cake: Protocol P3 has removed inherited protocol P2
cake: Struct fixedLayoutStruct has added a conformance to an existing protocol P2
cake: Struct fixedLayoutStruct has removed conformance to P1
/* Protocol Requirement Change */
cake1: Accessor HasMutatingMethodClone.bar.Get() now requires new witness table entry
cake1: AssociatedType AssociatedTypePro.T1 has removed default type Int
cake1: Func HasMutatingMethodClone.foo() now requires new witness table entry
cake2: AssociatedType RequiementChanges.addedTypeWithoutDefault has been added as a protocol requirement
cake2: Func RequiementChanges.addedFunc() has been added as a protocol requirement
cake2: Var RequiementChanges.addedVar has been added as a protocol requirement
cake: Accessor HasMutatingMethodClone.bar.Get() now requires new witness table entry
cake: AssociatedType AssociatedTypePro.T1 has removed default type Int
cake: AssociatedType RequiementChanges.addedTypeWithoutDefault has been added as a protocol requirement
cake: Func HasMutatingMethodClone.foo() now requires new witness table entry
cake: Func RequiementChanges.addedFunc() has been added as a protocol requirement
cake: Var RequiementChanges.addedVar has been added as a protocol requirement
/* Class Inheritance Change */
cake1: Class C4 has changed its super class from OldType to NewType
cake1: Class SubGenericClass has changed its super class from GenericClass<P1> to GenericClass<P2>
cake1: Class SuperClassRemoval has removed its super class C3
cake: Class C4 has changed its super class from OldType to NewType
cake: Class SubGenericClass has changed its super class from GenericClass<P1> to GenericClass<P2>
cake: Class SuperClassRemoval has removed its super class C3

View File

@@ -1,69 +1,69 @@
/* Generic Signature Changes */
cake1: Func P1.P1Constraint() has generic signature change from <Self where Self : P1, Self : P2> to <Self where Self : P1>
cake1: Protocol P3 has generic signature change from <Self : cake.P1, Self : cake.P2> to <Self : cake.P1, Self : cake.P4>
cake: Func P1.P1Constraint() has generic signature change from <Self where Self : P1, Self : P2> to <Self where Self : P1>
cake: Protocol P3 has generic signature change from <Self : cake.P1, Self : cake.P2> to <Self : cake.P1, Self : cake.P4>
/* RawRepresentable Changes */
/* Removed Decls */
Swift: Extension Int has been removed
cake1: Accessor GlobalVarChangedToLet.Set() has been removed
cake1: Accessor RemoveSetters.Value.Set() has been removed
cake1: AssociatedType RequiementChanges.removedType has been removed
cake1: Constructor Somestruct2.init(_:) has been removed
cake1: Func C4.foo() has been removed
cake1: Func RequiementChanges.removedFunc() has been removed
cake1: Subscript RemoveSetters.subscript(_:) has removed its setter
cake1: Var GlobalVarChangedToLet has removed its setter
cake1: Var RemoveSetters.Value has removed its setter
cake1: Var RequiementChanges.removedVar has been removed
cake: Accessor GlobalVarChangedToLet.Set() has been removed
cake: Accessor RemoveSetters.Value.Set() has been removed
cake: AssociatedType RequiementChanges.removedType has been removed
cake: Constructor Somestruct2.init(_:) has been removed
cake: Func C4.foo() has been removed
cake: Func RequiementChanges.removedFunc() has been removed
cake: Subscript RemoveSetters.subscript(_:) has removed its setter
cake: Var GlobalVarChangedToLet has removed its setter
cake: Var RemoveSetters.Value has removed its setter
cake: Var RequiementChanges.removedVar has been removed
/* Moved Decls */
cake1: Class ClassToStruct has been changed to a Struct
cake1: InfixOperator ..*.. has been changed to a PrefixOperator
cake1: Protocol ProtocolToEnum has been changed to a Enum
cake: Class ClassToStruct has been changed to a Struct
cake: InfixOperator ..*.. has been changed to a PrefixOperator
cake: Protocol ProtocolToEnum has been changed to a Enum
/* Renamed Decls */
cake1: Func S1.foo5(x:y:) has been renamed to Func foo5(x:y:z:)
cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
cake: Func S1.foo5(x:y:) has been renamed to Func foo5(x:y:z:)
cake: Struct Somestruct2 has been renamed to Struct NSSomestruct2
/* Type Changes */
cake1: AssociatedType AssociatedTypePro.T3 has default type change from C1 to C6
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
cake1: Func C7.foo(_:_:) has removed default argument from parameter 0
cake1: Func C7.foo(_:_:) has removed default argument from parameter 1
cake1: Func ownershipChange(_:_:) has parameter 0 changing from InOut to Default
cake1: Func ownershipChange(_:_:) has parameter 1 changing from Shared to Owned
cake1: TypeAlias TChangesFromIntToString.T has underlying type change from Int to String
cake: AssociatedType AssociatedTypePro.T3 has default type change from C1 to C6
cake: Constructor S1.init(_:) has parameter 0 type change from Int to Double
cake: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
cake: Func C7.foo(_:_:) has removed default argument from parameter 0
cake: Func C7.foo(_:_:) has removed default argument from parameter 1
cake: Func ownershipChange(_:_:) has parameter 0 changing from InOut to Default
cake: Func ownershipChange(_:_:) has parameter 1 changing from Shared to Owned
cake: TypeAlias TChangesFromIntToString.T has underlying type change from Int to String
/* Decl Attribute changes */
cake1: Func C1.foo1() is now not static
cake1: Func FinalFuncContainer.NewFinalFunc() is now with final
cake1: Func FinalFuncContainer.NoLongerFinalFunc() is now without final
cake1: Func HasMutatingMethodClone.foo() has self access kind changing from Mutating to NonMutating
cake1: Func S1.foo1() has self access kind changing from NonMutating to Mutating
cake1: Func S1.foo3() is now static
cake1: Var C1.CIIns1 changes from weak to strong
cake1: Var C1.CIIns2 changes from strong to weak
cake: Func C1.foo1() is now not static
cake: Func FinalFuncContainer.NewFinalFunc() is now with final
cake: Func FinalFuncContainer.NoLongerFinalFunc() is now without final
cake: Func HasMutatingMethodClone.foo() has self access kind changing from Mutating to NonMutating
cake: Func S1.foo1() has self access kind changing from NonMutating to Mutating
cake: Func S1.foo3() is now static
cake: Var C1.CIIns1 changes from weak to strong
cake: Var C1.CIIns2 changes from strong to weak
/* Conformance changes */
cake1: Func ObjCProtocol.removeOptional() is no longer an optional requirement
cake1: Protocol P3 has removed inherited protocol P2
cake1: Struct fixedLayoutStruct has removed conformance to P1
cake2: Protocol P3 has added inherited protocol P4
cake: Func ObjCProtocol.removeOptional() is no longer an optional requirement
cake: Protocol P3 has added inherited protocol P4
cake: Protocol P3 has removed inherited protocol P2
cake: Struct fixedLayoutStruct has removed conformance to P1
/* Protocol Requirement Change */
cake1: AssociatedType AssociatedTypePro.T1 has removed default type Int
cake2: AssociatedType RequiementChanges.addedTypeWithoutDefault has been added as a protocol requirement
cake2: Func RequiementChanges.addedFunc() has been added as a protocol requirement
cake2: Var RequiementChanges.addedVar has been added as a protocol requirement
cake1: Accessor ClassWithOpenMember.property.Get() is no longer open for subclassing
cake: AssociatedType AssociatedTypePro.T1 has removed default type Int
cake: AssociatedType RequiementChanges.addedTypeWithoutDefault has been added as a protocol requirement
cake: Func RequiementChanges.addedFunc() has been added as a protocol requirement
cake: Var RequiementChanges.addedVar has been added as a protocol requirement
cake: Accessor ClassWithOpenMember.property.Get() is no longer open for subclassing
/* Class Inheritance Change */
cake1: Class C4 has changed its super class from OldType to NewType
cake1: Class SubGenericClass has changed its super class from GenericClass<P1> to GenericClass<P2>
cake1: Class SuperClassRemoval has removed its super class C3
cake1: Func ClassWithOpenMember.bar() is no longer open for subclassing
cake1: Func ClassWithOpenMember.foo() is no longer open for subclassing
cake1: Var ClassWithOpenMember.property is no longer open for subclassing
cake: Class C4 has changed its super class from OldType to NewType
cake: Class SubGenericClass has changed its super class from GenericClass<P1> to GenericClass<P2>
cake: Class SuperClassRemoval has removed its super class C3
cake: Func ClassWithOpenMember.bar() is no longer open for subclassing
cake: Func ClassWithOpenMember.foo() is no longer open for subclassing
cake: Var ClassWithOpenMember.property is no longer open for subclassing

View File

@@ -0,0 +1,12 @@
// RUN: %empty-directory(%t.mod1)
// RUN: %empty-directory(%t.mod2)
// RUN: %empty-directory(%t.sdk)
// RUN: %empty-directory(%t.module-cache)
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod1/cake.swiftinterface %S/Inputs/cake_baseline/cake.swift -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod2/cake.swiftinterface %S/Inputs/cake_current/cake.swift -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
// RUN: %api-digester -diagnose-sdk -print-module -module cake -BI %t.mod1 -BI %S/Inputs/APINotesLeft -I %t.mod2 -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-cache-path %t.module-cache -o %t.result -abi
// RUN: %clang -E -P -x c %S/Outputs/Cake-abi.txt -o - | sed '/^\s*$/d' > %t.expected
// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
// RUN: diff -u %t.expected %t.result.tmp

View File

@@ -2,10 +2,10 @@
// RUN: %empty-directory(%t.mod2)
// RUN: %empty-directory(%t.sdk)
// RUN: %empty-directory(%t.module-cache)
// RUN: %swift -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake1.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource
// RUN: %swift -emit-module -o %t.mod2/cake.swiftmodule %S/Inputs/cake2.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft -abi | sed 's/"cake"/"cake1"/' > %t.dump1.json
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod2 -I %S/Inputs/APINotesLeft -abi | sed 's/"cake"/"cake2"/' > %t.dump2.json
// RUN: %swift -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake_baseline/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource
// RUN: %swift -emit-module -o %t.mod2/cake.swiftmodule %S/Inputs/cake_current/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft -abi > %t.dump1.json
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod2 -I %S/Inputs/APINotesLeft -abi > %t.dump2.json
// RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json -abi -o %t.result
// RUN: %clang -E -P -x c %S/Outputs/Cake-abi.txt -o - | sed '/^\s*$/d' > %t.abi.expected
// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.abi.result.tmp

View File

@@ -0,0 +1,12 @@
// RUN: %empty-directory(%t.mod1)
// RUN: %empty-directory(%t.mod2)
// RUN: %empty-directory(%t.sdk)
// RUN: %empty-directory(%t.module-cache)
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod1/cake.swiftinterface %S/Inputs/cake_baseline/cake.swift -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod2/cake.swiftinterface %S/Inputs/cake_current/cake.swift -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
// RUN: %api-digester -diagnose-sdk -print-module -module cake -BI %t.mod1 -BI %S/Inputs/APINotesLeft -I %t.mod2 -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-cache-path %t.module-cache -o %t.result
// RUN: %clang -E -P -x c %S/Outputs/Cake.txt -o - | sed '/^\s*$/d' > %t.expected
// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
// RUN: diff -u %t.expected %t.result.tmp

View File

@@ -2,10 +2,10 @@
// RUN: %empty-directory(%t.mod2)
// RUN: %empty-directory(%t.sdk)
// RUN: %empty-directory(%t.module-cache)
// RUN: %swift -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake1.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource
// RUN: %swift -emit-module -o %t.mod2/cake.swiftmodule %S/Inputs/cake2.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft | sed 's/"cake"/"cake1"/' > %t.dump1.json
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod2 -I %S/Inputs/APINotesLeft | sed 's/"cake"/"cake2"/' > %t.dump2.json
// RUN: %swift -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake_baseline/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -module-name cake
// RUN: %swift -emit-module -o %t.mod2/cake.swiftmodule %S/Inputs/cake_current/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-name cake
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft > %t.dump1.json
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod2 -I %S/Inputs/APINotesLeft > %t.dump2.json
// RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result
// RUN: %clang -E -P -x c %S/Outputs/Cake.txt -o - | sed '/^\s*$/d' > %t.expected

View File

@@ -1972,7 +1972,7 @@ swift::ide::api::getSDKNodeRoot(SDKContext &SDKCtx,
CheckerOptions Opts) {
CompilerInvocation Invocation(InitInvok);
CompilerInstance &CI = SDKCtx.getCompilerInstance();
CompilerInstance &CI = SDKCtx.newCompilerInstance();
// Display diagnostics to stderr.
PrintingDiagnosticConsumer PrintDiags;
CI.addDiagnosticConsumer(&PrintDiags);

View File

@@ -150,7 +150,7 @@ struct CheckerOptions {
};
class SDKContext {
CompilerInstance CI;
std::vector<std::unique_ptr<CompilerInstance>> CIs;
llvm::StringSet<> TextData;
llvm::BumpPtrAllocator Allocator;
SourceManager SourceMgr;
@@ -189,7 +189,6 @@ public:
DiagnosticEngine &getDiags() {
return Diags;
}
CompilerInstance &getCompilerInstance() { return CI; }
StringRef getPlatformIntroVersion(Decl *D, PlatformKind Kind);
StringRef getLanguageIntroVersion(Decl *D);
bool isEqual(const SDKNode &Left, const SDKNode &Right);
@@ -200,6 +199,11 @@ public:
ArrayRef<BreakingAttributeInfo> getBreakingAttributeInfo() const { return BreakingAttrs; }
Optional<uint8_t> getFixedBinaryOrder(ValueDecl *VD) const;
CompilerInstance &newCompilerInstance() {
CIs.emplace_back(new CompilerInstance());
return *CIs.back();
}
template<class YAMLNodeTy, typename ...ArgTypes>
void diagnose(YAMLNodeTy node, Diag<ArgTypes...> ID,
typename detail::PassArgument<ArgTypes>::type... args) {

View File

@@ -98,6 +98,10 @@ static llvm::cl::list<std::string>
FrameworkPaths("F", llvm::cl::desc("add a directory to the framework search path"),
llvm::cl::cat(Category));
static llvm::cl::list<std::string>
BaselineModuleInputPaths("BI", llvm::cl::desc("add a module for baseline input"),
llvm::cl::cat(Category));
static llvm::cl::list<std::string>
ModuleInputPaths("I", llvm::cl::desc("add a module for input"),
llvm::cl::cat(Category));
@@ -2074,6 +2078,33 @@ static void findTypeMemberDiffs(NodePtr leftSDKRoot, NodePtr rightSDKRoot,
}
}
static int diagnoseModuleChange(SDKContext &Ctx, SDKNodeRoot *LeftModule,
SDKNodeRoot *RightModule, StringRef OutputPath,
llvm::StringSet<> ProtocolReqWhitelist) {
assert(LeftModule);
assert(RightModule);
llvm::raw_ostream *OS = &llvm::errs();
std::unique_ptr<llvm::raw_ostream> FileOS;
if (!OutputPath.empty()) {
std::error_code EC;
FileOS.reset(new llvm::raw_fd_ostream(OutputPath, EC, llvm::sys::fs::F_None));
OS = FileOS.get();
}
ModuleDifferDiagsConsumer PDC(true, *OS);
Ctx.getDiags().addConsumer(PDC);
TypeAliasDiffFinder(LeftModule, RightModule,
Ctx.getTypeAliasUpdateMap()).search();
PrunePass Prune(Ctx, std::move(ProtocolReqWhitelist));
Prune.pass(LeftModule, RightModule);
ChangeRefinementPass RefinementPass(Ctx.getNodeUpdateMap());
RefinementPass.pass(LeftModule, RightModule);
// Find member hoist changes to help refine diagnostics.
findTypeMemberDiffs(LeftModule, RightModule, Ctx.getTypeMemberDiffs());
DiagnosisEmitter::diagnosis(LeftModule, RightModule, Ctx);
return 0;
}
static int diagnoseModuleChange(StringRef LeftPath, StringRef RightPath,
StringRef OutputPath,
CheckerOptions Opts,
@@ -2086,33 +2117,13 @@ static int diagnoseModuleChange(StringRef LeftPath, StringRef RightPath,
llvm::errs() << RightPath << " does not exist\n";
return 1;
}
llvm::raw_ostream *OS = &llvm::errs();
std::unique_ptr<llvm::raw_ostream> FileOS;
if (!OutputPath.empty()) {
std::error_code EC;
FileOS.reset(new llvm::raw_fd_ostream(OutputPath, EC, llvm::sys::fs::F_None));
OS = FileOS.get();
}
ModuleDifferDiagsConsumer PDC(true, *OS);
SDKContext Ctx(Opts);
Ctx.getDiags().addConsumer(PDC);
SwiftDeclCollector LeftCollector(Ctx);
LeftCollector.deSerialize(LeftPath);
SwiftDeclCollector RightCollector(Ctx);
RightCollector.deSerialize(RightPath);
auto LeftModule = LeftCollector.getSDKRoot();
auto RightModule = RightCollector.getSDKRoot();
TypeAliasDiffFinder(LeftModule, RightModule,
Ctx.getTypeAliasUpdateMap()).search();
PrunePass Prune(Ctx, std::move(ProtocolReqWhitelist));
Prune.pass(LeftModule, RightModule);
ChangeRefinementPass RefinementPass(Ctx.getNodeUpdateMap());
RefinementPass.pass(LeftModule, RightModule);
// Find member hoist changes to help refine diagnostics.
findTypeMemberDiffs(LeftModule, RightModule, Ctx.getTypeMemberDiffs());
DiagnosisEmitter::diagnosis(LeftModule, RightModule, Ctx);
diagnoseModuleChange(Ctx, LeftCollector.getSDKRoot(), RightCollector.getSDKRoot(),
OutputPath, std::move(ProtocolReqWhitelist));
return 0;
}
@@ -2261,7 +2272,8 @@ void anchorForGetMainExecutable() {}
static int prepareForDump(const char *Main,
CompilerInvocation &InitInvok,
llvm::StringSet<> &Modules) {
llvm::StringSet<> &Modules,
bool IsBaseline = false) {
InitInvok.setMainExecutablePath(fs::getMainExecutable(Main,
reinterpret_cast<void *>(&anchorForGetMainExecutable)));
InitInvok.setModuleName("swift_ide_test");
@@ -2311,17 +2323,18 @@ static int prepareForDump(const char *Main,
FramePaths.push_back({path, /*isSystem=*/true});
}
InitInvok.setFrameworkSearchPaths(FramePaths);
if (IsBaseline) {
InitInvok.setImportSearchPaths(options::BaselineModuleInputPaths);
} else {
InitInvok.setImportSearchPaths(options::ModuleInputPaths);
}
if (!options::ModuleList.empty()) {
if (readFileLineByLine(options::ModuleList, Modules))
return 1;
}
for (auto M : options::ModuleNames) {
Modules.insert(M);
}
if (Modules.empty()) {
llvm::errs() << "Need to specify -include-all or -module <name>\n";
return 1;
@@ -2384,6 +2397,15 @@ static CheckerOptions getCheckOpts() {
return Opts;
}
static SDKNodeRoot *getSDKRoot(const char *Main, SDKContext &Ctx,
CheckerOptions Opts, bool IsBaseline) {
CompilerInvocation Invok;
llvm::StringSet<> Modules;
if (prepareForDump(Main, Invok, Modules, IsBaseline))
return nullptr;
return getSDKNodeRoot(Ctx, Invok, Modules, Opts);
}
int main(int argc, char *argv[]) {
PROGRAM_START(argc, argv);
INITIALIZE_LLVM();
@@ -2405,7 +2427,8 @@ int main(int argc, char *argv[]) {
dumpSDKContent(InitInvok, Modules, options::OutputFile, Opts);
case ActionType::MigratorGen:
case ActionType::DiagnoseSDKs: {
if (options::SDKJsonPaths.size() != 2) {
bool CompareJson = options::SDKJsonPaths.size() == 2;
if (!CompareJson && options::BaselineModuleInputPaths.empty()) {
llvm::errs() << "Only two SDK versions can be compared\n";
llvm::cl::PrintHelpMessage();
return 1;
@@ -2419,11 +2442,18 @@ int main(int argc, char *argv[]) {
return generateMigrationScript(options::SDKJsonPaths[0],
options::SDKJsonPaths[1],
options::OutputFile, IgnoredUsrs, Opts);
else
else if (CompareJson)
return diagnoseModuleChange(options::SDKJsonPaths[0],
options::SDKJsonPaths[1],
options::OutputFile, Opts,
std::move(protocolWhitelist));
else {
SDKContext Ctx(Opts);
return diagnoseModuleChange(Ctx, getSDKRoot(argv[0], Ctx, Opts, true),
getSDKRoot(argv[0], Ctx, Opts, false),
options::OutputFile,
std::move(protocolWhitelist));
}
}
case ActionType::DeserializeSDK:
case ActionType::DeserializeDiffItems: {