// RUN: %empty-directory(%t) // RUN: cp %s %t/main.swift // RUN: %target-swift-frontend -disable-fine-grained-dependencies -typecheck -primary-file %t/main.swift %S/Inputs/reference-dependencies-helper.swift -emit-reference-dependencies-path - > %t.swiftdeps // RUN: %FileCheck -check-prefix=NEGATIVE %s < %t.swiftdeps // Check that the output is deterministic. // RUN: %target-swift-frontend -disable-fine-grained-dependencies -typecheck -primary-file %t/main.swift %S/Inputs/reference-dependencies-helper.swift -emit-reference-dependencies-path - > %t-2.swiftdeps // RUN: diff %t.swiftdeps %t-2.swiftdeps // CHECK-LABEL: {{^provides-top-level:$}} // CHECK-NEXT: "IntWrapper" // CHECK-NEXT: "==" // CHECK-NEXT: "<" // CHECK-NEXT: "***" // CHECK-NEXT: "^^^" // CHECK-NEXT: "Subclass" // CHECK-NEXT: "MyArray" // CHECK-NEXT: "someGlobal" // CHECK-NEXT: "ExpressibleByExtraFloatLiteral" // CHECK-NEXT: "~~~" // CHECK-NEXT: "ThreeTilde" // CHECK-NEXT: "overloadedOnProto" // CHECK-NEXT: "overloadedOnProto" // CHECK-NEXT: "~~~~" // CHECK-NEXT: "FourTilde" // CHECK-NEXT: "FourTildeImpl" // CHECK-NEXT: "FiveTildeImpl" // CHECK-NEXT: "topLevelComputedProperty" // CHECK-NEXT: "lookUpManyTopLevelNames" // CHECK-NEXT: "testOperators" // CHECK-NEXT: "TopLevelForMemberLookup" // CHECK-NEXT: "lookUpMembers" // CHECK-NEXT: "publicUseOfMember" // CHECK-NEXT: "Outer" // CHECK: "eof" // CHECK-NEXT: "~~~" // CHECK-NEXT: "~~~~" // CHECK-NEXT: "~~~~" // CHECK-NEXT: "~~~~~" // CHECK-LABEL: {{^provides-nominal:$}} // CHECK-NEXT: "4main10IntWrapperV" // CHECK-NEXT: "4main10IntWrapperV16InnerForNoReasonV" // CHECK-NEXT: "4main8SubclassC" // CHECK-NEXT: "Sb4mainE11InnerToBoolV" // CHECK: "4main9Sentinel1V" // CHECK-NEXT: "4main9Sentinel2V" // CHECK-LABEL: {{^provides-member:$}} // CHECK-NEXT: - ["4main10IntWrapperV", ""] // CHECK-NEXT: - ["4main10IntWrapperV16InnerForNoReasonV", ""] // CHECK-NEXT: - ["4main8SubclassC", ""] // CHECK-NEXT: - ["s25ExpressibleByArrayLiteralP", ""] // CHECK-NEXT: - ["Sb", ""] // CHECK-NEXT: - ["Sb4mainE11InnerToBoolV", ""] // CHECK: - ["4main9Sentinel1V", ""] // CHECK-NEXT: - ["4main9Sentinel2V", ""] // CHECK: - ["s25ExpressibleByArrayLiteralP", "useless"] // CHECK-NEXT: - ["s25ExpressibleByArrayLiteralP", "useless2"] // CHECK-NEXT: - ["Sb", "InnerToBool"] // CHECK-NEXT: - ["{{.*[0-9]}}FourTildeImplV", "~~~~"] // CHECK-NEXT: - ["{{.*[0-9]}}FiveTildeImplV", "~~~~~"] // CHECK-LABEL: {{^depends-top-level:$}} // CHECK-DAG: - "Comparable" struct IntWrapper: Comparable { // CHECK-DAG: - "Int" var value: Int struct InnerForNoReason {} // CHECK-DAG: - "TypeReferencedOnlyBySubscript" subscript(_: TypeReferencedOnlyBySubscript) -> Void { return () } // CHECK-DAG: - "TypeReferencedOnlyByPrivateSubscript" // FIXME: This should be marked "!private". private subscript(_: TypeReferencedOnlyByPrivateSubscript) -> Void { return () } } // CHECK-DAG: "IntWrapper" // CHECK-DAG: "Bool" func ==(lhs: IntWrapper, rhs: IntWrapper) -> Bool { // CHECK-DAG: "==" return lhs.value == rhs.value } func <(lhs: IntWrapper, rhs: IntWrapper) -> Bool { // CHECK-DAG: "<" return lhs.value < rhs.value } // Test operator lookup without a use of the same operator. // This is declared in the other file. // CHECK-DAG: "***" prefix func ***(lhs: IntWrapper) {} // This is provided as an operator but not implemented here. prefix operator ^^^ // CHECK-DAG: "ClassFromOtherFile" class Subclass : ClassFromOtherFile {} // CHECK-DAG: "Array" typealias MyArray = Array // CHECK-DAG: "ExpressibleByArrayLiteral" extension ExpressibleByArrayLiteral { func useless() {} } // CHECK-DAG: OtherFileElementType extension ExpressibleByArrayLiteral where ArrayLiteralElement == OtherFileElementType { func useless2() {} } // CHECK-DAG: "IntegerLiteralType" let someGlobal = 42 extension Bool { struct InnerToBool {} } // CHECK-DAG: - "ExpressibleByOtherFileAliasForFloatLiteral" protocol ExpressibleByExtraFloatLiteral : ExpressibleByOtherFileAliasForFloatLiteral { } // CHECK-DAG: - "ExpressibleByUnicodeScalarLiteral" private protocol ExpressibleByExtraCharLiteral : ExpressibleByUnicodeScalarLiteral { } prefix operator ~~~ protocol ThreeTilde { prefix static func ~~~(lhs: Self) } private struct ThreeTildeTypeImpl : ThreeTilde { } func overloadedOnProto(_: T) {} func overloadedOnProto(_: T) {} // CHECK-DAG: - "~~~" private prefix func ~~~(_: ThreeTildeTypeImpl) {} // CHECK-DAG: - "~~~~" prefix operator ~~~~ protocol FourTilde { prefix static func ~~~~(arg: Self) } struct FourTildeImpl : FourTilde {} extension FourTildeImpl { prefix static func ~~~~(arg: FourTildeImpl) {} } // CHECK-DAG: - "~~~~~" // ~~~~~ is declared in the other file. struct FiveTildeImpl {} extension FiveTildeImpl { prefix static func ~~~~~(arg: FiveTildeImpl) {} } var topLevelComputedProperty: Bool { return true } func lookUpManyTopLevelNames() { // CHECK-DAG: !private "Dictionary" let _: Dictionary = [1:1] // CHECK-DAG: !private "UInt" // CHECK-DAG: !private "+" let _: UInt = [1, 2].reduce(0, +) // CHECK-DAG: !private "-" let _: UInt = 3 - 2 - 1 // CHECK-DAG: !private "AliasFromOtherFile" let _: AliasFromOtherFile = 1 // CHECK-DAG: !private "funcFromOtherFile" funcFromOtherFile() // "CInt" is not used as a top-level name here. // CHECK-DAG: !private "StringLiteralType" // NEGATIVE-NOT: "CInt" _ = "abc" // NEGATIVE-NOT: - "max" print(Int.max) // NEGATIVE-NOT: - "Stride" let _: Int.Stride = 0 // CHECK-DAG: !private "OtherFileOuterType" _ = OtherFileOuterType.InnerType.sharedConstant _ = OtherFileOuterType.InnerType() // CHECK-DAG: !private "OtherFileAliasForSecret" _ = OtherFileAliasForSecret.constant // CHECK-DAG: !private "otherFileUse" // CHECK-DAG: !private "otherFileGetImpl" otherFileUse(otherFileGetImpl()) // CHECK-DAG: !private "otherFileUseGeneric" // CHECK-DAG: !private "otherFileGetImpl2" otherFileUseGeneric(otherFileGetImpl2()) // CHECK-DAG: !private "getOtherFileIntArray" for _ in getOtherFileIntArray() {} // CHECK-DAG: !private "getOtherFileEnum" switch getOtherFileEnum() { case .Value: break default: break } _ = .Value as OtherFileEnumWrapper.Enum let _: OtherFileEnumWrapper.Enum = .Value _ = OtherFileEnumWrapper.Enum.Value _ = { (_: PrivateTopLevelStruct.ValueType) -> PrivateTopLevelStruct2.ValueType? in return nil } typealias X = OtherFileEnumWrapper.Enum let value: Any = .Value as X switch value { case is OtherFileEnumWrapper.Enum: break default: break } // CHECK-DAG: !private "~=" switch 42 { case 50: break default: break } for _: OtherFileEnumWrapper.Enum in EmptyIterator() {} // CHECK-DAG: !private "otherFileGetNonImpl" overloadedOnProto(otherFileGetNonImpl()) } func testOperators(generic: T, specific: Flyswatter) { // CHECK-DAG: !private "****" // CHECK-DAG: !private "*****" // CHECK-DAG: !private "******" ****generic generic*****0 0******generic ****specific specific*****0 0******specific } struct TopLevelForMemberLookup { static func m1() {} static func m2() {} static func m3() {} } func lookUpMembers() { TopLevelForMemberLookup.m1() TopLevelForMemberLookup.m3() } public let publicUseOfMember: () = TopLevelForMemberLookup.m2() struct Outer { struct Inner { func method() { // CHECK-DAG: !private "CUnsignedInt" let _: CUnsignedInt = 5 } } } // CHECK-DAG: !private "privateFunc" private func privateFunc() {} // CHECK-DAG: - "topLevel1" var use1 = topLevel1() // CHECK-DAG: - "topLevel2" var use2 = { topLevel2() } // CHECK-DAG: - "topLevel3" var use3 = { ({ topLevel3() })() } // CHECK-DAG: - "topLevel4" // CHECK-DAG: - "TopLevelProto1" struct Use4 : TopLevelProto1 { var use4 = topLevel4() } // CHECK-DAG: - "*" _ = 42 * 30 // FIXME: Incorrectly marked non-private dependencies // CHECK-DAG: - "topLevel6" _ = topLevel6() // CHECK-DAG: - "topLevel7" private var use7 = topLevel7() // CHECK-DAG: - "topLevel8" var use8: Int = topLevel8() // CHECK-DAG: - "topLevel9" var use9 = { () -> Int in return topLevel9() } // CHECK-DAG: - "TopLevelTy1" func useTy1(_ x: TopLevelTy1) {} // CHECK-DAG: - "TopLevelTy2" func useTy2() -> TopLevelTy2 {} // CHECK-DAG: - "TopLevelTy3" // CHECK-DAG: - "TopLevelProto2" extension Use4 : TopLevelProto2 { var useTy3: TopLevelTy3? { return nil } } // CHECK-DAG: - "TopLevelStruct" // CHECK-DAG: - "TopLevelStruct2" let useTy4 = { (_: TopLevelStruct.ValueType) -> TopLevelStruct2.ValueType? in return nil } // CHECK-DAG: - "TopLevelStruct3" // CHECK-DAG: - "TopLevelStruct4" typealias useTy5 = TopLevelStruct3.ValueType let useTy6: TopLevelStruct4.ValueType = 0 struct StructForDeclaringProperties { // CHECK-DAG: - "TopLevelStruct5" var prop: TopLevelStruct5.ValueType { return 0 } } // CHECK-DAG: !private "privateTopLevel1" func private1(_ a: Int = privateTopLevel1()) {} // CHECK-DAG: - "privateTopLevel2" // CHECK-DAG: - "PrivateProto1" private struct Private2 : PrivateProto1 { var private2 = privateTopLevel2() } // CHECK-DAG: !private "privateTopLevel3" func outerPrivate3() { let _ = { privateTopLevel3() } } // CHECK-DAG: - "PrivateTopLevelTy1" private extension Use4 { var privateTy1: PrivateTopLevelTy1? { return nil } } // CHECK-DAG: - "PrivateTopLevelTy2" // CHECK-DAG: "PrivateProto2" extension Private2 : PrivateProto2 { // FIXME: This test is supposed to check that we get this behavior /without/ // marking the property private, just from the base type. private var privateTy2: PrivateTopLevelTy2? { return nil } } // CHECK-DAG: !private "PrivateTopLevelTy3" func outerPrivateTy3() { func inner(_ a: PrivateTopLevelTy3?) {} inner(nil) } // CHECK-DAG: - "PrivateTopLevelStruct3" private typealias PrivateTy4 = PrivateTopLevelStruct3.ValueType // CHECK-DAG: - "PrivateTopLevelStruct4" private func privateTy5(_ x: PrivateTopLevelStruct4.ValueType) -> PrivateTopLevelStruct4.ValueType { return x } // Deliberately empty. private struct PrivateTy6 {} // CHECK-DAG: - "PrivateProto3" extension PrivateTy6 : PrivateProto3 {} // CHECK-DAG: - "ProtoReferencedOnlyInGeneric" func genericTest(_: T) {} // CHECK-DAG: - "ProtoReferencedOnlyInPrivateGeneric" private func privateGenericTest(_: T) {} struct PrivateStoredProperty { // CHECK-DAG: - "TypeReferencedOnlyByPrivateVar" private var value: TypeReferencedOnlyByPrivateVar } class PrivateStoredPropertyRef { // CHECK-DAG: - "TypeReferencedOnlyByPrivateClassVar" private var value: TypeReferencedOnlyByPrivateClassVar? } struct Sentinel1 {} private protocol ExtensionProto {} extension OtherFileTypeToBeExtended : ExtensionProto { private func foo() {} } private extension OtherFileTypeToBeExtended { var bar: Bool { return false } } struct Sentinel2 {} // CHECK-LABEL: {{^depends-member:$}} // CHECK-DAG: - ["4main10IntWrapperV", "Int"] // CHECK-DAG: - ["4main10IntWrapperV", "deinit"] // CHECK-DAG: - ["SL", ""] // CHECK-DAG: - ["4main18ClassFromOtherFileC", ""] // CHECK-DAG: - !private ["Si", "max"] // CHECK-DAG: - ["s25ExpressibleByFloatLiteralP", ""] // CHECK-DAG: - !private ["s33ExpressibleByUnicodeScalarLiteralP", ""] // CHECK-DAG: - !private ["Sx", "Stride"] // CHECK-DAG: - !private ["Sa", "reduce"] // CHECK-DAG: - ["Sb", "InnerToBool"] // CHECK-DAG: - !private ["4main17OtherFileIntArrayV", "deinit"] // CHECK-DAG: - !private ["4main18OtherFileOuterTypeV", "InnerType"] // CHECK-DAG: - !private ["4main18OtherFileOuterTypeV05InnerE0V", "init"] // CHECK-DAG: - !private ["4main18OtherFileOuterTypeV05InnerE0V", "sharedConstant"] // CHECK-DAG: - !private ["4main26OtherFileSecretTypeWrapperV0dE0V", "constant"] // CHECK-DAG: - !private ["4main25OtherFileProtoImplementorV", "deinit"] // CHECK-DAG: - !private ["4main26OtherFileProtoImplementor2V", "deinit"] // CHECK-DAG: - !private ["s15EmptyCollectionV8IteratorV", "init"] // CHECK-DAG: - ["4main13OtherFileEnumO", "Value"] // CHECK-DAG: - !private ["4main20OtherFileEnumWrapperV", "Enum"] // CHECK-DAG: - ["4main14TopLevelStructV", "ValueType"] // CHECK-DAG: - ["4main15TopLevelStruct2V", "ValueType"] // CHECK-DAG: - ["4main15TopLevelStruct3V", "ValueType"] // CHECK-DAG: - ["4main15TopLevelStruct4V", "ValueType"] // CHECK-DAG: - ["4main15TopLevelStruct5V", "ValueType"] // CHECK-DAG: - !private ["4main21PrivateTopLevelStructV", "ValueType"] // CHECK-DAG: - !private ["4main22PrivateTopLevelStruct2V", "ValueType"] // CHECK-DAG: - ["4main22PrivateTopLevelStruct3V", "ValueType"] // CHECK-DAG: - ["4main22PrivateTopLevelStruct4V", "ValueType"] // CHECK-DAG: - ["4main14TopLevelProto1P", ""] // CHECK-DAG: - ["4main14TopLevelProto2P", ""] // CHECK-DAG: - !private ["4main13PrivateProto1P", ""] // CHECK-DAG: - !private ["4main13PrivateProto2P", ""] // CHECK-DAG: - !private ["4main13PrivateProto3P", ""] // CHECK-LABEL: {{^depends-nominal:$}} // We're checking order here to make sure the names are sorted. // CHECK: - !private "Sa" // CHECK: - "Sb" // CHECK: - "4main18ClassFromOtherFileC" // CHECK: - "SL" // CHECK: - "s25ExpressibleByFloatLiteralP" // CHECK: - !private "s33ExpressibleByUnicodeScalarLiteralP" // CHECK: - !private "4main18OtherFileOuterTypeV05InnerE0V" // CHECK: - !private "Si" // CHECK: - "4main10IntWrapperV" // CHECK: - "4main13OtherFileEnumO" // CHECK: - !private "4main20OtherFileEnumWrapperV" // CHECK: - !private "4main17OtherFileIntArrayV" // CHECK: - !private "4main18OtherFileOuterTypeV" // CHECK: - !private "4main25OtherFileProtoImplementorV" // CHECK: - !private "4main26OtherFileProtoImplementor2V" // CHECK: - "4main13PrivateProto1P" // CHECK: - "4main13PrivateProto2P" // CHECK: - !private "4main13PrivateProto3P" // CHECK: - !private "4main21PrivateTopLevelStructV" // CHECK: - !private "4main22PrivateTopLevelStruct2V" // CHECK: - "4main22PrivateTopLevelStruct3V" // CHECK: - "4main22PrivateTopLevelStruct4V" // CHECK: - !private "4main26OtherFileSecretTypeWrapperV0dE0V" // CHECK: - !private "Sx" // CHECK: - "4main23TopLevelForMemberLookupV" // CHECK: - "4main14TopLevelProto1P" // CHECK: - "4main14TopLevelProto2P" // CHECK: - "4main14TopLevelStructV" // CHECK: - "4main15TopLevelStruct2V" // CHECK: - "4main15TopLevelStruct3V" // CHECK: - "4main15TopLevelStruct4V" // CHECK: - "4main15TopLevelStruct5V" // String is not used anywhere in this file, though a string literal is. // NEGATIVE-NOT: "String" // These are used by the other file in this module, but not by this one. // NEGATIVE-NOT: "ExpressibleByFloatLiteral" // NEGATIVE-NOT: "Int16" // NEGATIVE-NOT: "OtherFileProto" // NEGATIVE-NOT: "OtherFileProtoImplementor" // NEGATIVE-NOT: "OtherFileProto2" // NEGATIVE-NOT: "OtherFileProtoImplementor2" // OtherFileSecretTypeWrapper is never used directly in this file. // NEGATIVE-NOT: "OtherFileSecretTypeWrapper" // NEGATIVE-NOT: "4main26OtherFileSecretTypeWrapperV" let eof: () = ()