diff --git a/src/swift/SwiftAPIView/SwiftAPIView.xcodeproj/xcshareddata/xcschemes/SwiftAPIView.xcscheme b/src/swift/SwiftAPIView/SwiftAPIView.xcodeproj/xcshareddata/xcschemes/SwiftAPIView.xcscheme index 498a6978cd3..b51af64a998 100644 --- a/src/swift/SwiftAPIView/SwiftAPIView.xcodeproj/xcshareddata/xcschemes/SwiftAPIView.xcscheme +++ b/src/swift/SwiftAPIView/SwiftAPIView.xcodeproj/xcshareddata/xcschemes/SwiftAPIView.xcscheme @@ -57,7 +57,7 @@ + isEnabled = "NO"> + isEnabled = "YES"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/AttributesExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/AttributesExpectFile.txt new file mode 100644 index 00000000000..bf627ece4f1 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/AttributesExpectFile.txt @@ -0,0 +1,25 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package AttributesTestFile.swifttxt { + public class ExampleClass: NSObject { + @objc public var enabled: Bool + } + + @available(iOS 10.0, macOS 10.12, *) + public class MyClass {} + + @available(*, unavailable, renamed: "MyRenamedProtocol") + public typealias MyProtocol = MyRenamedProtocol + + public protocol MyRenamedProtocol {} + + @available(swift 3.0.2) + @available(macOS 10.12, *) + public struct MyStruct {} + + public class SomeSendable: @unchecked Sendable { + public let name: String + public init(name: String) + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/EnumerationsExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/EnumerationsExpectFile.txt new file mode 100644 index 00000000000..ebb5393a1a5 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/EnumerationsExpectFile.txt @@ -0,0 +1,32 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package EnumerationsTestFile.swifttxt { + public enum ASCIIControlCharacter: Character { + case tab = "\t" + case lineFeed = "\n" + case carriageReturn = "\r" + } + + public enum ArithmeticExpression { + case number(Int) + indirect case addition(ArithmeticExpression, ArithmeticExpression) + indirect case multiplication(ArithmeticExpression, ArithmeticExpression) + } + + public enum Barcode { + case upc(Int, Int, Int, Int) + case qrCode(String) + } + + public enum CompassPoint { + case north + case south + case east + case west + } + + public enum Planet: Int { + case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/ExtensionExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/ExtensionExpectFile.txt new file mode 100644 index 00000000000..761c119f743 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/ExtensionExpectFile.txt @@ -0,0 +1,49 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package ExtensionTestFile.swifttxt { + public struct Point { + public var x = 0.0, y = 0.0 + } + + public struct Rect { + public var origin = Point() + public var size = Size() + } + + public extension Rect { + init(center: Point, size: Size) + } + + public struct Size { + public var width = 0.0, height = 0.0 + } + + \\ Non-package extensions + public extension Double { + var km: Double + var m: Double + var cm: Double + var mm: Double + var ft: Double + } + + public extension Int { + func repetitions(task: () -> Void) + public mutating func square() + public subscript(digitIndex: Int) -> Int + enum Kind { + case negative, zero, positive + } + var kind: Kind + } + + extension Stack { + public var count: Int + var underestimatedCount: Int + } + + extension Stack where Element: Equatable { + public func isTop(_: Element) -> Bool + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/FunctionsExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/FunctionsExpectFile.txt new file mode 100644 index 00000000000..f112f44fab0 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/FunctionsExpectFile.txt @@ -0,0 +1,23 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package FunctionsTestFile.swifttxt { + public struct FunctionTestClass { + public func funcWithoutParams() -> String + public func funcWithMultipleParams(person: String, alreadyGreeted: Bool) -> String + public func funcWithoutReturnValue(person: String) + public func funcWithReturnValue(string: String) -> Int + public func funcWithMultipleReturnValues(array: [Int]) -> (min: Int, max: Int)? + public func funcWithArgumentLabels(argumentLabel: Int) + public func funcWithoutArgumentLabels(_: Int, _: Int) + public func funcWithDefaultValue(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) + public func funcWithVariadicParam(_: Double...) -> Double + public func funcWithInOutParams(_: inout Int, _: inout Int) + public func addTwoInts(_: Int, _: Int) -> Int + public var mathFunction: (Int, Int) -> Int + public func funcWithFuncTypeParam(_: (Int, Int) -> Int, _: Int, _: Int) + public func funcWithFuncReturnType(backward: Bool) -> (Int) -> Int + public func funcWithEscapingClosure(completionHandler: @escaping () -> Void) + public func funcWithAutoclosureEscapingClosure(_: @autoclosure @escaping () -> String) + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/GenericsExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/GenericsExpectFile.txt new file mode 100644 index 00000000000..d409390ee80 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/GenericsExpectFile.txt @@ -0,0 +1,90 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package GenericsTestFile.swifttxt { + public protocol Container { + associatedtype Item: Equatable + mutating func append(_: Item) + var count: Int { get } + subscript(i: Int) -> Item { get } + } + + public extension Container { + func average() -> Double where Item == Int + func endsWith(_: Item) -> Bool where Item: Equatable + subscript(indices: Indices) -> [Item] where Indices.Iterator.Element == Int + } + + public extension Container where Item: Equatable { + func startsWith(_: Item) -> Bool + } + + public extension Container where Item == Double { + func average() -> Double + } + + public protocol ContainerAlt { + associatedtype Item + mutating func append(_: Item) + var count: Int { get } + subscript(i: Int) -> Item { get } + associatedtype Iterator: IteratorProtocol where Iterator.Element == Item + func makeIterator() -> Iterator + } + + public struct ContainerStack: Container { + public var items: [Element] = [] + public mutating func push(_: Element) + public mutating func pop() -> Element + public mutating func append(_: Element) + public var count: Int + public subscript(i: Int) -> Element + } + + extension ContainerStack: SuffixableContainer { + public func suffix(_: Int) -> ContainerStack + } + + public struct IntContainerStack: Container { + public typealias Item = Int + public mutating func append(_: Int) + public var count: Int + public subscript(i: Int) -> Int + } + + extension IntContainerStack: SuffixableContainer { + public func suffix(_: Int) -> ContainerStack + } + + public protocol Shape { + func draw() -> String + } + + public struct Square: Shape { + public var size: Int + public func draw() -> String + } + + public struct Stack { + public var items: [Element] = [] + public mutating func push(_: Element) + public mutating func pop() -> Element + } + + public extension Stack { + var topItem: Element? + } + + public protocol SuffixableContainer: Container { + associatedtype Suffix: SuffixableContainer where Suffix.Item == Item + func suffix(_: Int) -> Suffix + } + + public func allItemsMatch(_: C1, _: C2) -> Bool where C1.Item == C2.Item, C1.Item: Equatable + + public func findIndex(of: T, in: [T]) -> Int? + + public func makeTrapezoid() -> some Shape + + public func swapTwoValues(_: inout T, _: inout T) +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/InitializersExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/InitializersExpectFile.txt new file mode 100644 index 00000000000..4cf4f163072 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/InitializersExpectFile.txt @@ -0,0 +1,9 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package InitializersTestFile.swifttxt { + public class InitializersTestClass { + public init(withThrowable: String) throws + public init?(withFailable: String) + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/OperatorExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/OperatorExpectFile.txt new file mode 100644 index 00000000000..af4116e3a2b --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/OperatorExpectFile.txt @@ -0,0 +1,30 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package OperatorTestFile.swifttxt { + prefix operator +++ + + infix operator +-: AdditionPrecedence + + precedencegroup CongruentPrecedence { + lowerThan: MultiplicationPrecedence + higherThan: AdditionPrecedence + associativity: left + } + + public struct Vector2D { + public var x = 0.0, y = 0.0 + } + + public extension Vector2D { + static func +(left: Vector2D, right: Vector2D) -> Vector2D + static prefix func -(vector: Vector2D) -> Vector2D + static func +=(left: inout Vector2D, right: Vector2D) + static prefix func +++(vector: inout Vector2D) -> Vector2D + static func +-(left: Vector2D, right: Vector2D) -> Vector2D + } + + extension Vector2D: Equatable { + public static func ==(left: Vector2D, right: Vector2D) -> Bool + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/PrivateInternalExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/PrivateInternalExpectFile.txt new file mode 100644 index 00000000000..f3f4d9ffb29 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/PrivateInternalExpectFile.txt @@ -0,0 +1,5 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package PrivateInternalTestFile.swifttxt { +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/PropertiesExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/PropertiesExpectFile.txt new file mode 100644 index 00000000000..82dbc9a6234 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/PropertiesExpectFile.txt @@ -0,0 +1,10 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package PropertiesTestFile.swifttxt { + public class PropertiesTestClass { + public var totalSteps: Int = 0 { willSet(newTotalSteps) didSet } + public var someReadOnly: String + public var someReadWrite: String { get set } + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/ProtocolExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/ProtocolExpectFile.txt new file mode 100644 index 00000000000..644808185e5 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/ProtocolExpectFile.txt @@ -0,0 +1,120 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package ProtocolTestFile.swifttxt { + public protocol Aged { + var age: Int { get } + } + + public struct ComposedPerson: Named, Aged { + public var name: String + public var age: Int + } + + @objc + public protocol CounterDataSource { + @objc + optional func increment(forCount: Int) -> Int + @objc optional var fixedIncrement: Int { get } + } + + public class Dice { + public let sides: Int + public let generator: RandomNumberGenerator + public init(sides: Int, generator: RandomNumberGenerator) + public func roll() -> Int + } + + extension Dice: TextRepresentable { + public var textualDescription: String + } + + public protocol FullyNamed { + var fullName: String { get } + } + + public struct Hamster { + public var name: String + public var textualDescription: String + } + + extension Hamster: TextRepresentable { + } + + public protocol Named { + var name: String { get } + } + + public enum OnOffSwitch: Togglable { + case off, on + public mutating func toggle() + } + + public struct Person: FullyNamed { + public var fullName: String + } + + public protocol PrettyTextRepresentable: TextRepresentable { + var prettyTextualDescription: String { get } + } + + public extension PrettyTextRepresentable { + var prettyTextualDescription: String + } + + public protocol RandomNumberGenerator { + func random() -> Double + } + + public extension RandomNumberGenerator { + func randomBool() -> Bool + } + + public class SomeClass: SomeInitProtocol { + public required init(someParameter: Int) + } + + public protocol SomeClassOnlyProtocol: AnyObject, TextRepresentable {} + + public protocol SomeInitProtocol { + init(someParameter: Int) + } + + public protocol SomeOtherClassOnlyProtocol: class, TextRepresentable {} + + public protocol SomeOtherInitProtocol { + init() + } + + public protocol SomeProtocol { + var mustBeSettable: Int { get set } + var doesNotNeedToBeSettable: Int { get } + } + + public class SomeSubClass: SomeSuperClass, SomeOtherInitProtocol { + public required override init() + } + + open class SomeSuperClass { + public init() + } + + public protocol TextRepresentable { + var textualDescription: String { get } + } + + public protocol Togglable { + mutating func toggle() + } + + public func wishHappyBirthday(to: Named & Aged) + + \\ Non-package extensions + extension Array: TextRepresentable where Element: TextRepresentable { + public var textualDescription: String + } + + public extension Collection where Element: Equatable { + func allEqual() -> Bool + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/SwiftUIExpectFile.txt b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/SwiftUIExpectFile.txt new file mode 100644 index 00000000000..ec87bba046b --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/ExpectFiles/SwiftUIExpectFile.txt @@ -0,0 +1,10 @@ +Package parsed using Swift APIView (version 0.2.2) + + +package SwiftUITestFile.swifttxt { + public class ViewBuilderExample { + public func testViewBuilder(@ViewBuilder content: () -> Content) + @ViewBuilder + public func createView() -> some View + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/SwiftAPIViewCoreTests.swift b/src/swift/SwiftAPIViewCore/Tests/SwiftAPIViewCoreTests.swift index 8112a985dc8..e34345db9d7 100644 --- a/src/swift/SwiftAPIViewCore/Tests/SwiftAPIViewCoreTests.swift +++ b/src/swift/SwiftAPIViewCore/Tests/SwiftAPIViewCoreTests.swift @@ -30,37 +30,135 @@ import XCTest class SwiftAPIViewCoreTests: XCTestCase { override func setUpWithError() throws { + try super.setUpWithError() + continueAfterFailure = false SharedLogger.set(logger: NullLogger(), withLevel: .info) } - private func load(testFile filename: String) -> String { - let bundle = Bundle(for: Swift.type(of: self)) - return bundle.path(forResource: filename, ofType: "swifttxt")! + private func pathFor(testFile filename: String) -> String { + let bundle = Bundle(for: APIViewManager.self) + if let filePath = bundle.path(forResource: filename, ofType: "swifttxt") { + return filePath + } + XCTFail("Could not find file \(filename).swifttxt") + return "" } - private func load(expectFile filename: String) -> String { - let bundle = Bundle(for: Swift.type(of: self)) + private func contentsOf(expectFile filename: String) -> String { + let bundle = Bundle(for: APIViewManager.self) let path = bundle.path(forResource: filename, ofType: "txt")! return try! String(contentsOfFile: path) } private func compare(expected: String, actual: String) { - let actualLines = actual.split(separator: "\n").map { String($0) } - let expectedLines = expected.split(separator: "\n").map { String($0) } - print(actual) - XCTAssertEqual(actualLines.count, expectedLines.count) + let actualLines = actual.split(separator: "\n", omittingEmptySubsequences: false).map { String($0) } + let expectedLines = expected.split(separator: "\n", omittingEmptySubsequences: false).map { String($0) } for (i, expected) in expectedLines.enumerated() { let actual = actualLines[i] - XCTAssert(actual == expected, "Line \(i): (\(actual) is not equal to (\(expected)") + if (actual == expected) { + continue + } + XCTFail("Line \(i): (\(actual) is not equal to (\(expected)") } + XCTAssertEqual(actualLines.count, expectedLines.count, "Number of lines does not match") + } + + func testAttributes() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "AttributesTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "AttributesExpectFile") + compare(expected: expected, actual: generated) + } + + func testEnumerations() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "EnumerationsTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "EnumerationsExpectFile") + compare(expected: expected, actual: generated) + } + + func testExtensions() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "ExtensionTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "ExtensionExpectFile") + compare(expected: expected, actual: generated) + } + + func testFunctions() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "FunctionsTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "FunctionsExpectFile") + compare(expected: expected, actual: generated) + } + + func testGenerics() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "GenericsTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "GenericsExpectFile") + compare(expected: expected, actual: generated) + } + + func testInitializers() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "InitializersTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "InitializersExpectFile") + compare(expected: expected, actual: generated) + } + + func testOperators() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "OperatorTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "OperatorExpectFile") + compare(expected: expected, actual: generated) + } + + func testPrivateInternal() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "PrivateInternalTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "PrivateInternalExpectFile") + compare(expected: expected, actual: generated) + } + + func testProperties() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "PropertiesTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "PropertiesExpectFile") + compare(expected: expected, actual: generated) + } + + func testProtocols() throws { + let manager = APIViewManager(mode: .testing) + manager.config.sourcePath = pathFor(testFile: "ProtocolTestFile") + manager.config.packageVersion = "1.0.0" + let generated = try manager.run() + let expected = contentsOf(expectFile: "ProtocolExpectFile") + compare(expected: expected, actual: generated) } - func testFile1() throws { + func testSwiftUI() throws { let manager = APIViewManager(mode: .testing) - manager.config.sourcePath = load(testFile: "TestFile1") + manager.config.sourcePath = pathFor(testFile: "SwiftUITestFile") manager.config.packageVersion = "1.0.0" - let generated = try! manager.run() - let expected = load(expectFile: "ExpectFile1") + let generated = try manager.run() + let expected = contentsOf(expectFile: "SwiftUIExpectFile") compare(expected: expected, actual: generated) } } diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/AttributesTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/AttributesTestFile.swifttxt new file mode 100644 index 00000000000..070ec97e7f0 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/AttributesTestFile.swifttxt @@ -0,0 +1,69 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +// Using @available to rename a protocol + +public protocol MyRenamedProtocol { + // A protocol named MyProtocol was subsequent release renames MyProtocol +} + +@available(*, unavailable, renamed: "MyRenamedProtocol") +public typealias MyProtocol = MyRenamedProtocol + +// Using @available to specify OS versions + +@available(iOS 10.0, macOS 10.12, *) +public class MyClass { + // class definition +} + +// Using @available to specify swift version + +@available(swift 3.0.2) +@available(macOS 10.12, *) +public struct MyStruct { + // struct definition +} + +// Using @objc + +public class ExampleClass: NSObject { + @objc public var enabled: Bool { + return true + } +} + +// Use of @unchecked Sendable + +public class SomeSendable: @unchecked Sendable { + public let name: String + + public init(name: String) { + self.name = name + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/EnumerationsTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/EnumerationsTestFile.swifttxt new file mode 100644 index 00000000000..2c81bf1932a --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/EnumerationsTestFile.swifttxt @@ -0,0 +1,65 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +// Basic enum + +public enum CompassPoint { + case north + case south + case east + case west +} + +// Associated values + +public enum Barcode { + case upc(Int, Int, Int, Int) + case qrCode(String) +} + +// RawValue enum + +public enum ASCIIControlCharacter: Character { + case tab = "\t" + case lineFeed = "\n" + case carriageReturn = "\r" +} + +// Implicitly assigned value enum + +public enum Planet: Int { + case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune +} + +// Recursive enumeration + +public enum ArithmeticExpression { + case number(Int) + indirect case addition(ArithmeticExpression, ArithmeticExpression) + indirect case multiplication(ArithmeticExpression, ArithmeticExpression) +} diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/ExtensionTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/ExtensionTestFile.swifttxt new file mode 100644 index 00000000000..2029d8faf13 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/ExtensionTestFile.swifttxt @@ -0,0 +1,134 @@ + +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +// Computed properties on a package-defined type. Separate extensions--how to disambiguate? + +extension Stack { + public var count: Int { + return items.count + } +} + +public extension Stack { + var underestimatedCount: Int { + return items.underestimatedCount + } +} + +// An extension with a where clause + +extension Stack where Element: Equatable { + public func isTop(_ item: Element) -> Bool { + guard let topItem = items.last else { + return false + } + return topItem == item + } +} + +// Computed property on a Foundation type + +public extension Double { + var km: Double { return self * 1_000.0 } + var m: Double { return self } + var cm: Double { return self / 100.0 } + var mm: Double { return self / 1_000.0 } + var ft: Double { return self / 3.28084 } +} + +// Adding an initializer with an extension + +public struct Size { + public var width = 0.0, height = 0.0 +} + +public struct Point { + public var x = 0.0, y = 0.0 +} + +public struct Rect { + public var origin = Point() + public var size = Size() +} + +public extension Rect { + init(center: Point, size: Size) { + let originX = center.x - (size.width / 2) + let originY = center.y - (size.height / 2) + self.init(origin: Point(x: originX, y: originY), size: size) + } +} + +// Adding method to Foundation type + +public extension Int { + func repetitions(task: () -> Void) { + for _ in 0.. Int { + var decimalBase = 1 + for _ in 0.. 0: + return .positive + default: + return .negative + } + } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/FunctionsTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/FunctionsTestFile.swifttxt new file mode 100644 index 00000000000..b4ba53e858b --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/FunctionsTestFile.swifttxt @@ -0,0 +1,67 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + + +public struct FunctionTestClass { + + public func funcWithoutParams() -> String { "" } + + public func funcWithMultipleParams(person: String, alreadyGreeted: Bool) -> String { "" } + + public func funcWithoutReturnValue(person: String) { } + + public func funcWithReturnValue(string: String) -> Int { 1 } + + public func funcWithMultipleReturnValues(array: [Int]) -> (min: Int, max: Int)? { (0, 1) } + + public func funcWithArgumentLabels(argumentLabel parameterName: Int) { } + + public func funcWithoutArgumentLabels(_ firstParameterName: Int, _ secondParameterName: Int) { } + + public func funcWithDefaultValue(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) { } + + public func funcWithVariadicParam(_ numbers: Double...) -> Double { 1.0 } + + public func funcWithInOutParams(_ a: inout Int, _ b: inout Int) { } + + public func addTwoInts(_ a: Int, _ b: Int) -> Int { a + b } + + public var mathFunction: (Int, Int) -> Int + + public func funcWithFuncTypeParam(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) { } + + public func funcWithFuncReturnType(backward: Bool) -> (Int) -> Int { + func stepForward(input: Int) -> Int { return input + 1 } + func stepBackward(input: Int) -> Int { return input - 1 } + return backward ? stepBackward : stepForward + } + + public func funcWithEscapingClosure(completionHandler: @escaping () -> Void) { } + + public func funcWithAutoclosureEscapingClosure(_ customerProvider: @autoclosure @escaping () -> String) { } +} diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/GenericsTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/GenericsTestFile.swifttxt new file mode 100644 index 00000000000..0b5fae84ec3 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/GenericsTestFile.swifttxt @@ -0,0 +1,246 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +// Generic function + +public func swapTwoValues(_ a: inout T, _ b: inout T) { + let temporaryA = a + a = b + b = temporaryA +} + +// Generic object + +public struct Stack { + public var items: [Element] = [] + public mutating func push(_ item: Element) { + items.append(item) + } + public mutating func pop() -> Element { + return items.removeLast() + } +} + +// Extending generic + +public extension Stack { + var topItem: Element? { + return items.isEmpty ? nil : items[items.count - 1] + } +} + +// Generic type constraints + +public func findIndex(of valueToFind: T, in array:[T]) -> Int? { + for (index, value) in array.enumerated() { + if value == valueToFind { + return index + } + } + return nil +} + +// Associated type with constraint + +public struct ContainerStack: Container { + public var items: [Element] = [] + public mutating func push(_ item: Element) { + items.append(item) + } + public mutating func pop() -> Element { + return items.removeLast() + } + // conformance to the Container protocol + public mutating func append(_ item: Element) { + self.push(item) + } + public var count: Int { + return items.count + } + public subscript(i: Int) -> Element { + return items[i] + } +} + +public protocol Container { + associatedtype Item: Equatable + mutating func append(_ item: Item) + var count: Int { get } + subscript(i: Int) -> Item { get } +} + +public struct IntContainerStack: Container { + // original IntContainerStack implementation + var items: [Int] = [] + mutating func push(_ item: Int) { + items.append(item) + } + mutating func pop() -> Int { + return items.removeLast() + } + // conformance to the Container protocol + public typealias Item = Int + public mutating func append(_ item: Int) { + self.push(item) + } + public var count: Int { + return items.count + } + public subscript(i: Int) -> Int { + return items[i] + } +} + +// Using protocol in its associated type constraints + +public protocol SuffixableContainer: Container { + associatedtype Suffix: SuffixableContainer where Suffix.Item == Item + func suffix(_ size: Int) -> Suffix +} + +extension ContainerStack: SuffixableContainer { + public func suffix(_ size: Int) -> ContainerStack { + var result = ContainerStack() + for index in (count-size).. ContainerStack { + var result = ContainerStack() + for index in (count-size)... +} + +// Generic where clauses + +public func allItemsMatch + (_ someContainer: C1, _ anotherContainer: C2) -> Bool + where C1.Item == C2.Item, C1.Item: Equatable { + + // Check that both containers contain the same number of items. + if someContainer.count != anotherContainer.count { + return false + } + + // Check each pair of items to see if they're equivalent. + for i in 0.. Bool { + return count >= 1 && self[0] == item + } +} + +public extension Container where Item == Double { + func average() -> Double { + var sum = 0.0 + for index in 0.. Double where Item == Int { + var sum = 0.0 + for index in 0.. Bool where Item: Equatable { + return count >= 1 && self[count-1] == item + } +} + +// Associated type with generic where clause + +public protocol ContainerAlt { + associatedtype Item + mutating func append(_ item: Item) + var count: Int { get } + subscript(i: Int) -> Item { get } + + associatedtype Iterator: IteratorProtocol where Iterator.Element == Item + func makeIterator() -> Iterator +} + +// Generic subscripts + +public extension Container { + subscript(indices: Indices) -> [Item] + where Indices.Iterator.Element == Int { + var result: [Item] = [] + for index in indices { + result.append(self[index]) + } + return result + } +} + +// Opaque types + +public protocol Shape { + func draw() -> String +} + +public struct Square: Shape { + public var size: Int + public func draw() -> String { + let line = String(repeating: "*", count: size) + let result = Array(repeating: line, count: size) + return result.joined(separator: "\n") + } +} + +public func makeTrapezoid() -> some Shape { + // Some more implementation stuff goes here + return Square(size: 2) +} diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/InitializersTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/InitializersTestFile.swifttxt new file mode 100644 index 00000000000..0c15ba7cb7d --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/InitializersTestFile.swifttxt @@ -0,0 +1,38 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +public class InitializersTestClass { + + // Throwing initializer + + public init(withThrowable: String) throws {} + + // Failable initializer + + public init?(withFailable: String) {} +} diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/OperatorTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/OperatorTestFile.swifttxt new file mode 100644 index 00000000000..500cab6e2ef --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/OperatorTestFile.swifttxt @@ -0,0 +1,90 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +// Custom Operator Methods + +public struct Vector2D { + public var x = 0.0, y = 0.0 +} + +public extension Vector2D { + static func + (left: Vector2D, right: Vector2D) -> Vector2D { + return Vector2D(x: left.x + right.x, y: left.y + right.y) + } +} + +// Prefix operator extension + +public extension Vector2D { + static prefix func - (vector: Vector2D) -> Vector2D { + return Vector2D(x: -vector.x, y: -vector.y) + } +} + +// Compound assignment operator + +public extension Vector2D { + static func += (left: inout Vector2D, right: Vector2D) { + left = left + right + } +} + +// Equivalence operator + +extension Vector2D: Equatable { + public static func == (left: Vector2D, right: Vector2D) -> Bool { + return (left.x == right.x) && (left.y == right.y) + } +} + +// Custom operator + +prefix operator +++ +public extension Vector2D { + static prefix func +++ (vector: inout Vector2D) -> Vector2D { + vector += vector + return vector + } +} + +// Custom infix operator precedence + +infix operator +-: AdditionPrecedence +public extension Vector2D { + static func +- (left: Vector2D, right: Vector2D) -> Vector2D { + return Vector2D(x: left.x + right.x, y: left.y - right.y) + } +} + +// Custom precedence group + +precedencegroup CongruentPrecedence { + lowerThan: MultiplicationPrecedence + higherThan: AdditionPrecedence + associativity: left +} diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/PrivateInternalTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/PrivateInternalTestFile.swifttxt new file mode 100644 index 00000000000..ed4d03108f6 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/PrivateInternalTestFile.swifttxt @@ -0,0 +1,31 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +private struct _PrivateStruct {} +internal struct _InternalStruct {} +struct _ImplicitlyInternalStruct {} diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/PropertiesTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/PropertiesTestFile.swifttxt new file mode 100644 index 00000000000..65091177f78 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/PropertiesTestFile.swifttxt @@ -0,0 +1,59 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +public class PropertiesTestClass { + + public var totalSteps: Int = 0 { + willSet(newTotalSteps) { + print("About to set totalSteps to \(newTotalSteps)") + + } + didSet { + if totalSteps > oldValue { + print("Added \(totalSteps - oldValue) steps") + + } + } + } + + public var someReadOnly: String { + return "test" + } + + private var _secretValue: String = "" + public var someReadWrite: String { + get { + return "test" + } + + set { + self._secretValue = newValue + } + } +} + diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/ProtocolTestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/ProtocolTestFile.swifttxt new file mode 100644 index 00000000000..b52fec1b7a7 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/ProtocolTestFile.swifttxt @@ -0,0 +1,214 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +// Protocol with different get/set levels + +public protocol SomeProtocol { + var mustBeSettable: Int { get set } + var doesNotNeedToBeSettable: Int { get } +} + +// Protocol with property requirements + +public protocol FullyNamed { + var fullName: String { get } +} + +// Implementing protocol in declaration + +public struct Person: FullyNamed { + public var fullName: String +} + +// Protocol with method requirements + +public protocol RandomNumberGenerator { + func random() -> Double +} + +// Protocol with mutating function requirement + +public protocol Togglable { + mutating func toggle() +} + +public enum OnOffSwitch: Togglable { + case off, on + public mutating func toggle() { + switch self { + case .off: + self = .on + case .on: + self = .off + } + } +} + +// Protocol with initializer requirements + +public protocol SomeInitProtocol { + init(someParameter: Int) +} + +// Class implementation of protocol requirement + +public class SomeClass: SomeInitProtocol { + public required init(someParameter: Int) { + // initializer implementation goes here + } +} + +// Subclass overriding protocol and superclass initializer + +public protocol SomeOtherInitProtocol { + init() +} + +open class SomeSuperClass { + public init() { + // initializer implementation goes here + } +} + +public class SomeSubClass: SomeSuperClass, SomeOtherInitProtocol { + // "required" from SomeProtocol conformance; "override" from SomeSuperClass + public required override init() { + // initializer implementation goes here + } +} + +// Protocol conformance with extension + +public class Dice { + public let sides: Int + public let generator: RandomNumberGenerator + public init(sides: Int, generator: RandomNumberGenerator) { + self.sides = sides + self.generator = generator + } + public func roll() -> Int { + return Int(generator.random() * Double(sides)) + 1 + } +} + +public protocol TextRepresentable { + var textualDescription: String { get } +} + +extension Dice: TextRepresentable { + public var textualDescription: String { + return "A \(sides)-sided dice" + } +} + +// Adding condition protocol conformance with extension + +extension Array: TextRepresentable where Element: TextRepresentable { + public var textualDescription: String { + let itemsAsText = self.map { $0.textualDescription } + return "[" + itemsAsText.joined(separator: ", ") + "]" + } +} + +// Declaring protocol adoption with extension + +public struct Hamster { + public var name: String + public var textualDescription: String { + return "A hamster named \(name)" + } +} +extension Hamster: TextRepresentable {} + +// Protocol inheritance + +public protocol PrettyTextRepresentable: TextRepresentable { + var prettyTextualDescription: String { get } +} + +// Class-only protocols + +public protocol SomeClassOnlyProtocol: AnyObject, TextRepresentable { + // class-only protocol definition goes here +} + +public protocol SomeOtherClassOnlyProtocol: class, TextRepresentable { + // class-only protocol definition goes here +} + +// Protocol composition + +public protocol Named { + var name: String { get } +} +public protocol Aged { + var age: Int { get } +} +public struct ComposedPerson: Named, Aged { + public var name: String + public var age: Int +} +public func wishHappyBirthday(to celebrator: Named & Aged) { + print("Happy birthday, \(celebrator.name), you're \(celebrator.age)!") +} + +// Optional protocol requirements + +@objc public protocol CounterDataSource { + @objc optional func increment(forCount count: Int) -> Int + @objc optional var fixedIncrement: Int { get } +} + +// Protocol extensions + +public extension RandomNumberGenerator { + func randomBool() -> Bool { + return random() > 0.5 + } +} + +// Providing default implementations of protocol with extension +public extension PrettyTextRepresentable { + var prettyTextualDescription: String { + return textualDescription + } +} + +// Adding constraints to protocol extensions + +public extension Collection where Element: Equatable { + func allEqual() -> Bool { + for element in self { + if element != self.first { + return false + } + } + return true + } +} + diff --git a/src/swift/SwiftAPIViewCore/Tests/TestFiles/SwiftUITestFile.swifttxt b/src/swift/SwiftAPIViewCore/Tests/TestFiles/SwiftUITestFile.swifttxt new file mode 100644 index 00000000000..89f82e4be17 --- /dev/null +++ b/src/swift/SwiftAPIViewCore/Tests/TestFiles/SwiftUITestFile.swifttxt @@ -0,0 +1,38 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation +import SwiftUI + +public class ViewBuilderExample { + public func testViewBuilder(@ViewBuilder content: () -> Content) { + self.content = content + } + + @ViewBuilder public func createView() -> some View { + return Button() + } +}