mirror of
https://github.com/krzysztofzablocki/Sourcery.git
synced 2026-04-07 19:17:40 +00:00
Fix associatedtype generics (#1345)
* Preliminary associatedtype support
* Implemented associatedtype support with generic requirements
* Fixed failing test
* Squashed commit of the following:
commit 9d01e6f99a
Author: Ruslan A <r.alikhamov@gmail.com>
Date: Fri Jun 14 20:06:41 2024 +0400
Improved concurrency support in SwiftTemplate caching (#1344)
* Removed test code
* Removed comment
* Updated Linux classes
* update internal boilerplate code.
* Updated generated code
* Removed warnings
* Updated expected file
* Updated expected file
* Adjusted protocol type for Linux
* Removed protocol composition due to Swift compiler crash under Linux
This commit is contained in:
@@ -246,16 +246,37 @@ class SyntaxTreeCollector: SyntaxVisitor {
|
||||
let name = node.name.text.trimmed
|
||||
var typeName: TypeName?
|
||||
var type: Type?
|
||||
|
||||
if let possibleTypeName = node.inheritanceClause?.inheritedTypes.description.trimmed {
|
||||
var genericRequirements: [GenericRequirement] = []
|
||||
if let genericWhereClause = node.genericWhereClause {
|
||||
genericRequirements = genericWhereClause.requirements.compactMap { requirement in
|
||||
if let sameType = requirement.requirement.as(SameTypeRequirementSyntax.self) {
|
||||
return GenericRequirement(sameType)
|
||||
} else if let conformanceType = requirement.requirement.as(ConformanceRequirementSyntax.self) {
|
||||
return GenericRequirement(conformanceType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if let composition = processPossibleProtocolComposition(for: possibleTypeName, localName: "") {
|
||||
type = composition
|
||||
} else {
|
||||
type = Protocol(name: possibleTypeName, genericRequirements: genericRequirements)
|
||||
}
|
||||
typeName = TypeName(possibleTypeName)
|
||||
} else if let possibleTypeName = (node.initializer?.value as? TypeSyntax)?.description.trimmed {
|
||||
type = processPossibleProtocolComposition(for: possibleTypeName, localName: "")
|
||||
typeName = TypeName(possibleTypeName)
|
||||
} else {
|
||||
type = Type(name: "Any")
|
||||
typeName = TypeName(name: "Any", actualTypeName: TypeName(name: "Any"))
|
||||
}
|
||||
|
||||
sourceryProtocol.associatedTypes[name] = AssociatedType(name: name, typeName: typeName, type: type)
|
||||
return .skipChildren
|
||||
}
|
||||
|
||||
|
||||
public override func visit(_ node: OperatorDeclSyntax) -> SyntaxVisitorContinueKind {
|
||||
return .skipChildren
|
||||
}
|
||||
|
||||
@@ -6,8 +6,12 @@ import Foundation
|
||||
@objc(SwiftActor) @objcMembers
|
||||
#endif
|
||||
public final class Actor: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "actor" }
|
||||
|
||||
/// Returns "actor"
|
||||
public override var kind: String { return "actor" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Whether type is final
|
||||
public var isFinal: Bool {
|
||||
@@ -36,7 +40,8 @@ public final class Actor: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Actor.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -54,7 +59,8 @@ public final class Actor: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,11 @@ import Foundation
|
||||
@objc(SwiftClass) @objcMembers
|
||||
#endif
|
||||
public final class Class: Type {
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "class" }
|
||||
|
||||
/// Returns "class"
|
||||
public override var kind: String { return "class" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Whether type is final
|
||||
public var isFinal: Bool {
|
||||
@@ -30,7 +33,8 @@ public final class Class: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Class.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -48,7 +52,8 @@ public final class Class: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,17 +8,20 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
#if canImport(ObjectiveC)
|
||||
|
||||
/// :nodoc:
|
||||
public typealias SourceryProtocol = Protocol
|
||||
|
||||
/// Describes Swift protocol
|
||||
#if canImport(ObjectiveC)
|
||||
@objcMembers
|
||||
#endif
|
||||
public final class Protocol: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "protocol" }
|
||||
|
||||
/// Returns "protocol"
|
||||
public override var kind: String { return "protocol" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// list of all declared associated types with their names as keys
|
||||
public var associatedTypes: [String: AssociatedType] {
|
||||
@@ -52,7 +55,8 @@ public final class Protocol: Type {
|
||||
modifiers: [SourceryModifier] = [],
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Protocol.kind) {
|
||||
self.associatedTypes = associatedTypes
|
||||
super.init(
|
||||
name: name,
|
||||
@@ -71,7 +75,8 @@ public final class Protocol: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: !associatedTypes.isEmpty || !genericRequirements.isEmpty,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -132,3 +137,4 @@ public final class Protocol: Type {
|
||||
}
|
||||
// sourcery:end
|
||||
}
|
||||
#endif
|
||||
@@ -9,8 +9,11 @@ import Foundation
|
||||
#endif
|
||||
public final class ProtocolComposition: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "protocolComposition" }
|
||||
|
||||
/// Returns "protocolComposition"
|
||||
public override var kind: String { return "protocolComposition" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// The names of the types composed to form this composition
|
||||
public let composedTypeNames: [TypeName]
|
||||
@@ -35,7 +38,8 @@ public final class ProtocolComposition: Type {
|
||||
isGeneric: Bool = false,
|
||||
composedTypeNames: [TypeName] = [],
|
||||
composedTypes: [Type]? = nil,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = ProtocolComposition.kind) {
|
||||
self.composedTypeNames = composedTypeNames
|
||||
self.composedTypes = composedTypes
|
||||
super.init(
|
||||
@@ -51,7 +55,8 @@ public final class ProtocolComposition: Type {
|
||||
typealiases: typealiases,
|
||||
annotations: annotations,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,11 @@ import Foundation
|
||||
#endif
|
||||
public final class Struct: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "struct" }
|
||||
|
||||
/// Returns "struct"
|
||||
public override var kind: String { return "struct" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// :nodoc:
|
||||
public override init(name: String = "",
|
||||
@@ -35,7 +38,8 @@ public final class Struct: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Struct.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -53,7 +57,8 @@ public final class Struct: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@ public enum Composer {
|
||||
let composed = ParserResultsComposed(parserResult: parserResult)
|
||||
|
||||
let resolveType = { (typeName: TypeName, containingType: Type?) -> Type? in
|
||||
return composed.resolveType(typeName: typeName, containingType: containingType)
|
||||
composed.resolveType(typeName: typeName, containingType: containingType)
|
||||
}
|
||||
|
||||
let methodResolveType = { (typeName: TypeName, containingType: Type?, method: Method) -> Type? in
|
||||
return composed.resolveType(typeName: typeName, containingType: containingType, method: method)
|
||||
composed.resolveType(typeName: typeName, containingType: containingType, method: method)
|
||||
}
|
||||
|
||||
let processType = { (type: Type) in
|
||||
@@ -52,7 +52,7 @@ public enum Composer {
|
||||
}
|
||||
|
||||
if let sourceryProtocol = type as? SourceryProtocol {
|
||||
resolveProtocolTypes(sourceryProtocol, resolve: resolveType)
|
||||
resolveAssociatedTypes(sourceryProtocol, resolve: resolveType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,11 +180,13 @@ public enum Composer {
|
||||
protocolComposition.composedTypes = composedTypes
|
||||
}
|
||||
|
||||
private static func resolveProtocolTypes(_ sourceryProtocol: SourceryProtocol, resolve: TypeResolver) {
|
||||
private static func resolveAssociatedTypes(_ sourceryProtocol: SourceryProtocol, resolve: TypeResolver) {
|
||||
sourceryProtocol.associatedTypes.forEach { (_, value) in
|
||||
guard let typeName = value.typeName,
|
||||
let type = resolve(typeName, sourceryProtocol)
|
||||
else { return }
|
||||
else {
|
||||
return
|
||||
}
|
||||
value.type = type
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ internal struct ParserResultsComposed {
|
||||
let parsedTypes: [Type]
|
||||
let functions: [SourceryMethod]
|
||||
let resolvedTypealiases: [String: Typealias]
|
||||
let associatedTypes: [String: AssociatedType]
|
||||
let unresolvedTypealiases: [String: Typealias]
|
||||
|
||||
init(parserResult: FileParserResult) {
|
||||
@@ -23,6 +24,7 @@ internal struct ParserResultsComposed {
|
||||
let aliases = Self.typealiases(parserResult)
|
||||
resolvedTypealiases = aliases.resolved
|
||||
unresolvedTypealiases = aliases.unresolved
|
||||
associatedTypes = Self.extractAssociatedTypes(parserResult)
|
||||
parsedTypes = parserResult.types
|
||||
|
||||
// set definedInType for all methods and variables
|
||||
@@ -51,6 +53,11 @@ internal struct ParserResultsComposed {
|
||||
alias.type = resolveType(typeName: alias.typeName, containingType: alias.parent)
|
||||
}
|
||||
|
||||
/// Map associated types
|
||||
associatedTypes.forEach {
|
||||
typeMap[$0.key] = $0.value.type
|
||||
}
|
||||
|
||||
types = unifyTypes()
|
||||
}
|
||||
|
||||
@@ -96,7 +103,7 @@ internal struct ParserResultsComposed {
|
||||
resolveExtensionOfNestedType(type)
|
||||
}
|
||||
|
||||
if let resolved = resolveGlobalName(for: oldName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases)?.name {
|
||||
if let resolved = resolveGlobalName(for: oldName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases, associatedTypes: associatedTypes)?.name {
|
||||
var moduleName: String = ""
|
||||
if let module = type.module {
|
||||
moduleName = "\(module)."
|
||||
@@ -116,7 +123,7 @@ internal struct ParserResultsComposed {
|
||||
// extend all types with their extensions
|
||||
parsedTypes.forEach { type in
|
||||
let inheritedTypes: [[String]] = type.inheritedTypes.compactMap { inheritedName in
|
||||
if let resolvedGlobalName = resolveGlobalName(for: inheritedName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases)?.name {
|
||||
if let resolvedGlobalName = resolveGlobalName(for: inheritedName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases, associatedTypes: associatedTypes)?.name {
|
||||
return [resolvedGlobalName]
|
||||
}
|
||||
if let baseType = Composer.findBaseType(for: type, name: inheritedName, typesByName: typeMap) {
|
||||
@@ -175,6 +182,14 @@ internal struct ParserResultsComposed {
|
||||
})
|
||||
}
|
||||
|
||||
// extract associated types from all types and add them to types
|
||||
private static func extractAssociatedTypes(_ parserResult: FileParserResult) -> [String: AssociatedType] {
|
||||
parserResult.types
|
||||
.compactMap { $0 as? SourceryProtocol }
|
||||
.map { $0.associatedTypes }
|
||||
.flatMap { $0 }.reduce(into: [:]) { $0[$1.key] = $1.value }
|
||||
}
|
||||
|
||||
/// returns typealiases map to their full names, with `resolved` removing intermediate
|
||||
/// typealises and `unresolved` including typealiases that reference other typealiases.
|
||||
private static func typealiases(_ parserResult: FileParserResult) -> (resolved: [String: Typealias], unresolved: [String: Typealias]) {
|
||||
@@ -207,11 +222,14 @@ internal struct ParserResultsComposed {
|
||||
}
|
||||
|
||||
/// Resolves type identifier for name
|
||||
func resolveGlobalName(for type: String,
|
||||
containingType: Type? = nil,
|
||||
unique: [String: Type]? = nil,
|
||||
modules: [String: [String: Type]],
|
||||
typealiases: [String: Typealias]) -> (name: String, typealias: Typealias?)? {
|
||||
func resolveGlobalName(
|
||||
for type: String,
|
||||
containingType: Type? = nil,
|
||||
unique: [String: Type]? = nil,
|
||||
modules: [String: [String: Type]],
|
||||
typealiases: [String: Typealias],
|
||||
associatedTypes: [String: AssociatedType]
|
||||
) -> (name: String, typealias: Typealias?)? {
|
||||
// if the type exists for this name and isn't an extension just return it's name
|
||||
// if it's extension we need to check if there aren't other options TODO: verify
|
||||
if let realType = unique?[type], realType.isExtension == false {
|
||||
@@ -222,6 +240,13 @@ internal struct ParserResultsComposed {
|
||||
return (name: alias.type?.globalName ?? alias.typeName.name, typealias: alias)
|
||||
}
|
||||
|
||||
if let associatedType = associatedTypes[type],
|
||||
let actualType = associatedType.type
|
||||
{
|
||||
let typeName = associatedType.typeName ?? TypeName(name: actualType.name)
|
||||
return (name: actualType.globalName, typealias: Typealias(aliasName: type, typeName: typeName))
|
||||
}
|
||||
|
||||
if let containingType = containingType {
|
||||
if type == "Self" {
|
||||
return (name: containingType.globalName, typealias: nil)
|
||||
@@ -231,7 +256,7 @@ internal struct ParserResultsComposed {
|
||||
while currentContainer != nil, let parentName = currentContainer?.globalName {
|
||||
/// TODO: no parent for sure?
|
||||
/// manually walk the containment tree
|
||||
if let name = resolveGlobalName(for: "\(parentName).\(type)", containingType: nil, unique: unique, modules: modules, typealiases: typealiases) {
|
||||
if let name = resolveGlobalName(for: "\(parentName).\(type)", containingType: nil, unique: unique, modules: modules, typealiases: typealiases, associatedTypes: associatedTypes) {
|
||||
return name
|
||||
}
|
||||
|
||||
@@ -565,20 +590,27 @@ internal struct ParserResultsComposed {
|
||||
}
|
||||
}
|
||||
|
||||
return unique[resolvedIdentifier]
|
||||
if let associatedType = associatedTypes[resolvedIdentifier] {
|
||||
return associatedType.type
|
||||
}
|
||||
|
||||
return unique[resolvedIdentifier] ?? unique[typeName.name]
|
||||
}
|
||||
|
||||
private func actualTypeName(for typeName: TypeName,
|
||||
containingType: Type? = nil) -> TypeName? {
|
||||
containingType: Type? = nil) -> TypeName? {
|
||||
let unique = typeMap
|
||||
let typealiases = resolvedTypealiases
|
||||
let associatedTypes = associatedTypes
|
||||
|
||||
var unwrapped = typeName.unwrappedTypeName
|
||||
if let generic = typeName.generic {
|
||||
unwrapped = generic.name
|
||||
} else if let type = associatedTypes[unwrapped] {
|
||||
unwrapped = type.name
|
||||
}
|
||||
|
||||
guard let aliased = resolveGlobalName(for: unwrapped, containingType: containingType, unique: unique, modules: modules, typealiases: typealiases) else {
|
||||
guard let aliased = resolveGlobalName(for: unwrapped, containingType: containingType, unique: unique, modules: modules, typealiases: typealiases, associatedTypes: associatedTypes) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,12 @@ public final class Enum: Type {
|
||||
}
|
||||
}
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "enum" }
|
||||
|
||||
// sourcery: skipDescription
|
||||
/// Returns "enum"
|
||||
public override var kind: String { return "enum" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Enum cases
|
||||
public var cases: [EnumCase]
|
||||
@@ -93,7 +96,7 @@ public final class Enum: Type {
|
||||
self.rawTypeName = rawTypeName
|
||||
self.hasRawType = rawTypeName != nil || !inheritedTypes.isEmpty
|
||||
|
||||
super.init(name: name, parent: parent, accessLevel: accessLevel, isExtension: isExtension, variables: variables, methods: methods, inheritedTypes: inheritedTypes, containedTypes: containedTypes, typealiases: typealiases, attributes: attributes, modifiers: modifiers, annotations: annotations, documentation: documentation, isGeneric: isGeneric)
|
||||
super.init(name: name, parent: parent, accessLevel: accessLevel, isExtension: isExtension, variables: variables, methods: methods, inheritedTypes: inheritedTypes, containedTypes: containedTypes, typealiases: typealiases, attributes: attributes, modifiers: modifiers, annotations: annotations, documentation: documentation, isGeneric: isGeneric, kind: Self.kind)
|
||||
|
||||
if let rawTypeName = rawTypeName?.name, let index = self.inheritedTypes.firstIndex(of: rawTypeName) {
|
||||
self.inheritedTypes.remove(at: index)
|
||||
|
||||
@@ -374,25 +374,25 @@ public final class Method: NSObject, SourceryModel, Annotated, Documented, Defin
|
||||
|
||||
/// :nodoc:
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
guard let name: String = aDecoder.decode(forKey: "name") else {
|
||||
guard let name: String = aDecoder.decode(forKey: "name") else {
|
||||
withVaList(["name"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self.name = name
|
||||
guard let selectorName: String = aDecoder.decode(forKey: "selectorName") else {
|
||||
guard let selectorName: String = aDecoder.decode(forKey: "selectorName") else {
|
||||
withVaList(["selectorName"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self.selectorName = selectorName
|
||||
guard let parameters: [MethodParameter] = aDecoder.decode(forKey: "parameters") else {
|
||||
guard let parameters: [MethodParameter] = aDecoder.decode(forKey: "parameters") else {
|
||||
withVaList(["parameters"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self.parameters = parameters
|
||||
guard let returnTypeName: TypeName = aDecoder.decode(forKey: "returnTypeName") else {
|
||||
guard let returnTypeName: TypeName = aDecoder.decode(forKey: "returnTypeName") else {
|
||||
withVaList(["returnTypeName"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
@@ -402,7 +402,7 @@ public final class Method: NSObject, SourceryModel, Annotated, Documented, Defin
|
||||
self.isAsync = aDecoder.decode(forKey: "isAsync")
|
||||
self.`throws` = aDecoder.decode(forKey: "`throws`")
|
||||
self.`rethrows` = aDecoder.decode(forKey: "`rethrows`")
|
||||
guard let accessLevel: String = aDecoder.decode(forKey: "accessLevel") else {
|
||||
guard let accessLevel: String = aDecoder.decode(forKey: "accessLevel") else {
|
||||
withVaList(["accessLevel"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
@@ -411,13 +411,13 @@ public final class Method: NSObject, SourceryModel, Annotated, Documented, Defin
|
||||
self.isStatic = aDecoder.decode(forKey: "isStatic")
|
||||
self.isClass = aDecoder.decode(forKey: "isClass")
|
||||
self.isFailableInitializer = aDecoder.decode(forKey: "isFailableInitializer")
|
||||
guard let annotations: Annotations = aDecoder.decode(forKey: "annotations") else {
|
||||
guard let annotations: Annotations = aDecoder.decode(forKey: "annotations") else {
|
||||
withVaList(["annotations"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self.annotations = annotations
|
||||
guard let documentation: Documentation = aDecoder.decode(forKey: "documentation") else {
|
||||
guard let documentation: Documentation = aDecoder.decode(forKey: "documentation") else {
|
||||
withVaList(["documentation"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
@@ -425,25 +425,25 @@ public final class Method: NSObject, SourceryModel, Annotated, Documented, Defin
|
||||
}; self.documentation = documentation
|
||||
self.definedInTypeName = aDecoder.decode(forKey: "definedInTypeName")
|
||||
self.definedInType = aDecoder.decode(forKey: "definedInType")
|
||||
guard let attributes: AttributeList = aDecoder.decode(forKey: "attributes") else {
|
||||
guard let attributes: AttributeList = aDecoder.decode(forKey: "attributes") else {
|
||||
withVaList(["attributes"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self.attributes = attributes
|
||||
guard let modifiers: [SourceryModifier] = aDecoder.decode(forKey: "modifiers") else {
|
||||
guard let modifiers: [SourceryModifier] = aDecoder.decode(forKey: "modifiers") else {
|
||||
withVaList(["modifiers"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self.modifiers = modifiers
|
||||
guard let genericRequirements: [GenericRequirement] = aDecoder.decode(forKey: "genericRequirements") else {
|
||||
guard let genericRequirements: [GenericRequirement] = aDecoder.decode(forKey: "genericRequirements") else {
|
||||
withVaList(["genericRequirements"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self.genericRequirements = genericRequirements
|
||||
guard let genericParameters: [GenericParameter] = aDecoder.decode(forKey: "genericParameters") else {
|
||||
guard let genericParameters: [GenericParameter] = aDecoder.decode(forKey: "genericParameters") else {
|
||||
withVaList(["genericParameters"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// Protocol.swift
|
||||
// Sourcery
|
||||
//
|
||||
// Created by Krzysztof Zablocki on 09/12/2016.
|
||||
// Copyright © 2016 Pixle. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
#if !canImport(ObjectiveC)
|
||||
|
||||
/// :nodoc:
|
||||
public typealias SourceryProtocol = Protocol
|
||||
|
||||
/// Describes Swift protocol
|
||||
public final class Protocol: Type {
|
||||
public override subscript(dynamicMember member: String) -> Any? {
|
||||
switch member {
|
||||
case "associatedTypes":
|
||||
return associatedTypes
|
||||
default:
|
||||
return super[dynamicMember: member]
|
||||
}
|
||||
}
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "protocol" }
|
||||
|
||||
/// Returns "protocol"
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// list of all declared associated types with their names as keys
|
||||
public var associatedTypes: [String: AssociatedType] {
|
||||
didSet {
|
||||
isGeneric = !associatedTypes.isEmpty || !genericRequirements.isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
// sourcery: skipCoding
|
||||
/// list of generic requirements
|
||||
public override var genericRequirements: [GenericRequirement] {
|
||||
didSet {
|
||||
isGeneric = !associatedTypes.isEmpty || !genericRequirements.isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
public init(name: String = "",
|
||||
parent: Type? = nil,
|
||||
accessLevel: AccessLevel = .internal,
|
||||
isExtension: Bool = false,
|
||||
variables: [Variable] = [],
|
||||
methods: [Method] = [],
|
||||
subscripts: [Subscript] = [],
|
||||
inheritedTypes: [String] = [],
|
||||
containedTypes: [Type] = [],
|
||||
typealiases: [Typealias] = [],
|
||||
associatedTypes: [String: AssociatedType] = [:],
|
||||
genericRequirements: [GenericRequirement] = [],
|
||||
attributes: AttributeList = [:],
|
||||
modifiers: [SourceryModifier] = [],
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Protocol.kind) {
|
||||
self.associatedTypes = associatedTypes
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
accessLevel: accessLevel,
|
||||
isExtension: isExtension,
|
||||
variables: variables,
|
||||
methods: methods,
|
||||
subscripts: subscripts,
|
||||
inheritedTypes: inheritedTypes,
|
||||
containedTypes: containedTypes,
|
||||
typealiases: typealiases,
|
||||
genericRequirements: genericRequirements,
|
||||
attributes: attributes,
|
||||
modifiers: modifiers,
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: !associatedTypes.isEmpty || !genericRequirements.isEmpty,
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
// sourcery: skipJSExport
|
||||
override public var description: String {
|
||||
var string = super.description
|
||||
string.append(", ")
|
||||
string.append("kind = \(String(describing: self.kind)), ")
|
||||
string.append("associatedTypes = \(String(describing: self.associatedTypes)), ")
|
||||
return string
|
||||
}
|
||||
|
||||
override public func diffAgainst(_ object: Any?) -> DiffableResult {
|
||||
let results = DiffableResult()
|
||||
guard let castObject = object as? Protocol else {
|
||||
results.append("Incorrect type <expected: Protocol, received: \(Swift.type(of: object))>")
|
||||
return results
|
||||
}
|
||||
results.append(contentsOf: DiffableResult(identifier: "associatedTypes").trackDifference(actual: self.associatedTypes, expected: castObject.associatedTypes))
|
||||
results.append(contentsOf: super.diffAgainst(castObject))
|
||||
return results
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
// sourcery: skipJSExport
|
||||
public override var hash: Int {
|
||||
var hasher = Hasher()
|
||||
hasher.combine(self.associatedTypes)
|
||||
hasher.combine(super.hash)
|
||||
return hasher.finalize()
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
public override func isEqual(_ object: Any?) -> Bool {
|
||||
guard let rhs = object as? Protocol else { return false }
|
||||
if self.associatedTypes != rhs.associatedTypes { return false }
|
||||
return super.isEqual(rhs)
|
||||
}
|
||||
|
||||
// sourcery:inline:Protocol.AutoCoding
|
||||
|
||||
/// :nodoc:
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
guard let associatedTypes: [String: AssociatedType] = aDecoder.decode(forKey: "associatedTypes") else {
|
||||
withVaList(["associatedTypes"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self.associatedTypes = associatedTypes
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
override public func encode(with aCoder: NSCoder) {
|
||||
super.encode(with: aCoder)
|
||||
aCoder.encode(self.associatedTypes, forKey: "associatedTypes")
|
||||
}
|
||||
// sourcery:end
|
||||
}
|
||||
#endif
|
||||
@@ -92,7 +92,11 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
|
||||
// sourcery: forceEquality
|
||||
/// Kind of type declaration, i.e. `enum`, `struct`, `class`, `protocol` or `extension`
|
||||
public var kind: String { isExtension ? "extension" : "unknown" }
|
||||
public var kind: String { isExtension ? "extension" : _kind }
|
||||
|
||||
// sourcery: skipJSExport
|
||||
/// Kind of a backing store for `self.kind`
|
||||
private var _kind: String
|
||||
|
||||
/// Type access level, i.e. `internal`, `private`, `fileprivate`, `public`, `open`
|
||||
public let accessLevel: String
|
||||
@@ -422,7 +426,8 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = "unknown") {
|
||||
self.localName = name
|
||||
self.accessLevel = accessLevel.rawValue
|
||||
self.isExtension = isExtension
|
||||
@@ -441,6 +446,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
self.isGeneric = isGeneric
|
||||
self.genericRequirements = genericRequirements
|
||||
self.implements = implements
|
||||
self._kind = kind
|
||||
super.init()
|
||||
containedTypes.forEach {
|
||||
containedType[$0.localName] = $0
|
||||
@@ -471,13 +477,15 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
/// :nodoc:
|
||||
// sourcery: skipJSExport
|
||||
override public var description: String {
|
||||
var string = "\(Swift.type(of: self)): "
|
||||
let type: Type.Type = Swift.type(of: self)
|
||||
var string = "\(type): "
|
||||
string.append("module = \(String(describing: self.module)), ")
|
||||
string.append("imports = \(String(describing: self.imports)), ")
|
||||
string.append("allImports = \(String(describing: self.allImports)), ")
|
||||
string.append("typealiases = \(String(describing: self.typealiases)), ")
|
||||
string.append("isExtension = \(String(describing: self.isExtension)), ")
|
||||
string.append("kind = \(String(describing: self.kind)), ")
|
||||
string.append("_kind = \(String(describing: self._kind)), ")
|
||||
string.append("accessLevel = \(String(describing: self.accessLevel)), ")
|
||||
string.append("name = \(String(describing: self.name)), ")
|
||||
string.append("isUnknownExtension = \(String(describing: self.isUnknownExtension)), ")
|
||||
@@ -613,6 +621,12 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
fatalError()
|
||||
}; self.typealiases = typealiases
|
||||
self.isExtension = aDecoder.decode(forKey: "isExtension")
|
||||
guard let _kind: String = aDecoder.decode(forKey: "_kind") else {
|
||||
withVaList(["_kind"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self._kind = _kind
|
||||
guard let accessLevel: String = aDecoder.decode(forKey: "accessLevel") else {
|
||||
withVaList(["accessLevel"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
@@ -731,6 +745,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
aCoder.encode(self.imports, forKey: "imports")
|
||||
aCoder.encode(self.typealiases, forKey: "typealiases")
|
||||
aCoder.encode(self.isExtension, forKey: "isExtension")
|
||||
aCoder.encode(self._kind, forKey: "_kind")
|
||||
aCoder.encode(self.accessLevel, forKey: "accessLevel")
|
||||
aCoder.encode(self.isGeneric, forKey: "isGeneric")
|
||||
aCoder.encode(self.localName, forKey: "localName")
|
||||
|
||||
@@ -9,9 +9,13 @@ import Foundation
|
||||
/// Defines Swift enum
|
||||
@objcMembers
|
||||
public final class Enum: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "enum" }
|
||||
|
||||
// sourcery: skipDescription
|
||||
/// Returns "enum"
|
||||
public override var kind: String { return "enum" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Enum cases
|
||||
public var cases: [EnumCase]
|
||||
@@ -83,7 +87,7 @@ public final class Enum: Type {
|
||||
self.rawTypeName = rawTypeName
|
||||
self.hasRawType = rawTypeName != nil || !inheritedTypes.isEmpty
|
||||
|
||||
super.init(name: name, parent: parent, accessLevel: accessLevel, isExtension: isExtension, variables: variables, methods: methods, inheritedTypes: inheritedTypes, containedTypes: containedTypes, typealiases: typealiases, attributes: attributes, modifiers: modifiers, annotations: annotations, documentation: documentation, isGeneric: isGeneric)
|
||||
super.init(name: name, parent: parent, accessLevel: accessLevel, isExtension: isExtension, variables: variables, methods: methods, inheritedTypes: inheritedTypes, containedTypes: containedTypes, typealiases: typealiases, attributes: attributes, modifiers: modifiers, annotations: annotations, documentation: documentation, isGeneric: isGeneric, kind: Self.kind)
|
||||
|
||||
if let rawTypeName = rawTypeName?.name, let index = self.inheritedTypes.firstIndex(of: rawTypeName) {
|
||||
self.inheritedTypes.remove(at: index)
|
||||
|
||||
@@ -404,7 +404,7 @@ public final class Method: NSObject, SourceryModel, Annotated, Documented, Defin
|
||||
}
|
||||
fatalError()
|
||||
}; self.genericRequirements = genericRequirements
|
||||
guard let genericParameters: [GenericParameter] = aDecoder.decode(forKey: "genericParameters") else {
|
||||
guard let genericParameters: [GenericParameter] = aDecoder.decode(forKey: "genericParameters") else {
|
||||
withVaList(["genericParameters"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,11 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
|
||||
// sourcery: forceEquality
|
||||
/// Kind of type declaration, i.e. `enum`, `struct`, `class`, `protocol` or `extension`
|
||||
public var kind: String { isExtension ? "extension" : "unknown" }
|
||||
public var kind: String { isExtension ? "extension" : _kind }
|
||||
|
||||
// sourcery: skipJSExport
|
||||
/// Kind of a backing store for `self.kind`
|
||||
private var _kind: String
|
||||
|
||||
/// Type access level, i.e. `internal`, `private`, `fileprivate`, `public`, `open`
|
||||
public let accessLevel: String
|
||||
@@ -378,7 +382,8 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = "unknown") {
|
||||
self.localName = name
|
||||
self.accessLevel = accessLevel.rawValue
|
||||
self.isExtension = isExtension
|
||||
@@ -397,6 +402,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
self.isGeneric = isGeneric
|
||||
self.genericRequirements = genericRequirements
|
||||
self.implements = implements
|
||||
self._kind = kind
|
||||
super.init()
|
||||
containedTypes.forEach {
|
||||
containedType[$0.localName] = $0
|
||||
@@ -435,6 +441,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
string.append("typealiases = \(String(describing: self.typealiases)), ")
|
||||
string.append("isExtension = \(String(describing: self.isExtension)), ")
|
||||
string.append("kind = \(String(describing: self.kind)), ")
|
||||
string.append("_kind = \(String(describing: self._kind)), ")
|
||||
string.append("accessLevel = \(String(describing: self.accessLevel)), ")
|
||||
string.append("name = \(String(describing: self.name)), ")
|
||||
string.append("isUnknownExtension = \(String(describing: self.isUnknownExtension)), ")
|
||||
@@ -570,6 +577,12 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
fatalError()
|
||||
}; self.typealiases = typealiases
|
||||
self.isExtension = aDecoder.decode(forKey: "isExtension")
|
||||
guard let _kind: String = aDecoder.decode(forKey: "_kind") else {
|
||||
withVaList(["_kind"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self._kind = _kind
|
||||
guard let accessLevel: String = aDecoder.decode(forKey: "accessLevel") else {
|
||||
withVaList(["accessLevel"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
@@ -688,6 +701,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
aCoder.encode(self.imports, forKey: "imports")
|
||||
aCoder.encode(self.typealiases, forKey: "typealiases")
|
||||
aCoder.encode(self.isExtension, forKey: "isExtension")
|
||||
aCoder.encode(self._kind, forKey: "_kind")
|
||||
aCoder.encode(self.accessLevel, forKey: "accessLevel")
|
||||
aCoder.encode(self.isGeneric, forKey: "isGeneric")
|
||||
aCoder.encode(self.localName, forKey: "localName")
|
||||
|
||||
@@ -63,6 +63,7 @@ public final class StencilTemplate: StencilSwiftKit.StencilSwiftTemplate {
|
||||
ext.registerAccessLevelFilters(.private)
|
||||
ext.registerAccessLevelFilters(.fileprivate)
|
||||
ext.registerAccessLevelFilters(.internal)
|
||||
ext.registerAccessLevelFilters(.package)
|
||||
|
||||
ext.registerBoolFilterOrWithArguments("based",
|
||||
filter: { (t: Type, name: String) in t.based[name] != nil },
|
||||
@@ -86,6 +87,14 @@ public final class StencilTemplate: StencilSwiftKit.StencilSwiftTemplate {
|
||||
ext.registerFilter("isEmpty", filter: isEmpty)
|
||||
ext.registerFilter("reversed", filter: reversed)
|
||||
ext.registerFilter("toArray", filter: toArray)
|
||||
ext.registerFilter("sortedValuesByKeys", filter: sortedValuesByKeys)
|
||||
ext.registerFilter("last", filter: last)
|
||||
|
||||
ext.registerFilterWithArguments("push") { arg1, arg2 in
|
||||
var array = arg1 as? [Any] ?? []
|
||||
array.append(arg2)
|
||||
return array
|
||||
}
|
||||
|
||||
#if canImport(ObjectiveC)
|
||||
ext.registerFilterWithArguments("sorted") { (array, propertyName: String) -> Any? in
|
||||
@@ -172,7 +181,6 @@ public final class StencilTemplate: StencilSwiftKit.StencilSwiftTemplate {
|
||||
public extension Annotated {
|
||||
|
||||
func isAnnotated(with annotation: String) -> Bool {
|
||||
|
||||
if annotation.contains("=") {
|
||||
let components = annotation.components(separatedBy: "=").map({ $0.trimmingCharacters(in: .whitespaces) })
|
||||
var keyPath = components[0].components(separatedBy: ".")
|
||||
@@ -284,6 +292,29 @@ public extension Stencil.Extension {
|
||||
|
||||
}
|
||||
|
||||
private func last(_ value: Any?) -> Any? {
|
||||
switch value {
|
||||
case let arr as NSArray:
|
||||
return arr.lastObject
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func sortedValuesByKeys(_ value: Any?) -> Any? {
|
||||
switch value {
|
||||
case let dict as NSDictionary:
|
||||
let keys = dict.allKeys.sorted { (($0 as? String) ?? "" < ($1 as? String) ?? "") }
|
||||
var retVal: [Any?] = []
|
||||
for key in keys {
|
||||
retVal.append(dict[key])
|
||||
}
|
||||
return retVal
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func toArray(_ value: Any?) -> Any? {
|
||||
switch value {
|
||||
case let array as NSArray:
|
||||
@@ -310,11 +341,15 @@ private func count(_ value: Any?) -> Any? {
|
||||
}
|
||||
|
||||
private func isEmpty(_ value: Any?) -> Any? {
|
||||
guard let array = value as? NSArray else {
|
||||
return false
|
||||
switch value {
|
||||
case let array as NSArray:
|
||||
// swiftlint:disable:next empty_count
|
||||
array.count == 0
|
||||
case let string as NSString:
|
||||
string.length == 0
|
||||
default:
|
||||
false
|
||||
}
|
||||
// swiftlint:disable:next empty_count
|
||||
return array.count == 0
|
||||
}
|
||||
|
||||
private struct Filter<T> {
|
||||
|
||||
@@ -31,8 +31,12 @@ import Foundation
|
||||
@objc(SwiftActor) @objcMembers
|
||||
#endif
|
||||
public final class Actor: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "actor" }
|
||||
|
||||
/// Returns "actor"
|
||||
public override var kind: String { return "actor" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Whether type is final
|
||||
public var isFinal: Bool {
|
||||
@@ -61,7 +65,8 @@ public final class Actor: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Actor.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -79,7 +84,8 @@ public final class Actor: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -620,8 +626,11 @@ import Foundation
|
||||
@objc(SwiftClass) @objcMembers
|
||||
#endif
|
||||
public final class Class: Type {
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "class" }
|
||||
|
||||
/// Returns "class"
|
||||
public override var kind: String { return "class" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Whether type is final
|
||||
public var isFinal: Bool {
|
||||
@@ -645,7 +654,8 @@ public final class Class: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Class.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -663,7 +673,8 @@ public final class Class: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -746,11 +757,11 @@ public enum Composer {
|
||||
let composed = ParserResultsComposed(parserResult: parserResult)
|
||||
|
||||
let resolveType = { (typeName: TypeName, containingType: Type?) -> Type? in
|
||||
return composed.resolveType(typeName: typeName, containingType: containingType)
|
||||
composed.resolveType(typeName: typeName, containingType: containingType)
|
||||
}
|
||||
|
||||
let methodResolveType = { (typeName: TypeName, containingType: Type?, method: Method) -> Type? in
|
||||
return composed.resolveType(typeName: typeName, containingType: containingType, method: method)
|
||||
composed.resolveType(typeName: typeName, containingType: containingType, method: method)
|
||||
}
|
||||
|
||||
let processType = { (type: Type) in
|
||||
@@ -773,7 +784,7 @@ public enum Composer {
|
||||
}
|
||||
|
||||
if let sourceryProtocol = type as? SourceryProtocol {
|
||||
resolveProtocolTypes(sourceryProtocol, resolve: resolveType)
|
||||
resolveAssociatedTypes(sourceryProtocol, resolve: resolveType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,11 +912,13 @@ public enum Composer {
|
||||
protocolComposition.composedTypes = composedTypes
|
||||
}
|
||||
|
||||
private static func resolveProtocolTypes(_ sourceryProtocol: SourceryProtocol, resolve: TypeResolver) {
|
||||
private static func resolveAssociatedTypes(_ sourceryProtocol: SourceryProtocol, resolve: TypeResolver) {
|
||||
sourceryProtocol.associatedTypes.forEach { (_, value) in
|
||||
guard let typeName = value.typeName,
|
||||
let type = resolve(typeName, sourceryProtocol)
|
||||
else { return }
|
||||
else {
|
||||
return
|
||||
}
|
||||
value.type = type
|
||||
}
|
||||
|
||||
@@ -2218,6 +2231,7 @@ internal struct ParserResultsComposed {
|
||||
let parsedTypes: [Type]
|
||||
let functions: [SourceryMethod]
|
||||
let resolvedTypealiases: [String: Typealias]
|
||||
let associatedTypes: [String: AssociatedType]
|
||||
let unresolvedTypealiases: [String: Typealias]
|
||||
|
||||
init(parserResult: FileParserResult) {
|
||||
@@ -2228,6 +2242,7 @@ internal struct ParserResultsComposed {
|
||||
let aliases = Self.typealiases(parserResult)
|
||||
resolvedTypealiases = aliases.resolved
|
||||
unresolvedTypealiases = aliases.unresolved
|
||||
associatedTypes = Self.extractAssociatedTypes(parserResult)
|
||||
parsedTypes = parserResult.types
|
||||
|
||||
// set definedInType for all methods and variables
|
||||
@@ -2256,6 +2271,11 @@ internal struct ParserResultsComposed {
|
||||
alias.type = resolveType(typeName: alias.typeName, containingType: alias.parent)
|
||||
}
|
||||
|
||||
/// Map associated types
|
||||
associatedTypes.forEach {
|
||||
typeMap[$0.key] = $0.value.type
|
||||
}
|
||||
|
||||
types = unifyTypes()
|
||||
}
|
||||
|
||||
@@ -2301,7 +2321,7 @@ internal struct ParserResultsComposed {
|
||||
resolveExtensionOfNestedType(type)
|
||||
}
|
||||
|
||||
if let resolved = resolveGlobalName(for: oldName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases)?.name {
|
||||
if let resolved = resolveGlobalName(for: oldName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases, associatedTypes: associatedTypes)?.name {
|
||||
var moduleName: String = ""
|
||||
if let module = type.module {
|
||||
moduleName = "\\(module)."
|
||||
@@ -2321,7 +2341,7 @@ internal struct ParserResultsComposed {
|
||||
// extend all types with their extensions
|
||||
parsedTypes.forEach { type in
|
||||
let inheritedTypes: [[String]] = type.inheritedTypes.compactMap { inheritedName in
|
||||
if let resolvedGlobalName = resolveGlobalName(for: inheritedName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases)?.name {
|
||||
if let resolvedGlobalName = resolveGlobalName(for: inheritedName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases, associatedTypes: associatedTypes)?.name {
|
||||
return [resolvedGlobalName]
|
||||
}
|
||||
if let baseType = Composer.findBaseType(for: type, name: inheritedName, typesByName: typeMap) {
|
||||
@@ -2380,6 +2400,14 @@ internal struct ParserResultsComposed {
|
||||
})
|
||||
}
|
||||
|
||||
// extract associated types from all types and add them to types
|
||||
private static func extractAssociatedTypes(_ parserResult: FileParserResult) -> [String: AssociatedType] {
|
||||
parserResult.types
|
||||
.compactMap { $0 as? SourceryProtocol }
|
||||
.map { $0.associatedTypes }
|
||||
.flatMap { $0 }.reduce(into: [:]) { $0[$1.key] = $1.value }
|
||||
}
|
||||
|
||||
/// returns typealiases map to their full names, with `resolved` removing intermediate
|
||||
/// typealises and `unresolved` including typealiases that reference other typealiases.
|
||||
private static func typealiases(_ parserResult: FileParserResult) -> (resolved: [String: Typealias], unresolved: [String: Typealias]) {
|
||||
@@ -2412,11 +2440,14 @@ internal struct ParserResultsComposed {
|
||||
}
|
||||
|
||||
/// Resolves type identifier for name
|
||||
func resolveGlobalName(for type: String,
|
||||
containingType: Type? = nil,
|
||||
unique: [String: Type]? = nil,
|
||||
modules: [String: [String: Type]],
|
||||
typealiases: [String: Typealias]) -> (name: String, typealias: Typealias?)? {
|
||||
func resolveGlobalName(
|
||||
for type: String,
|
||||
containingType: Type? = nil,
|
||||
unique: [String: Type]? = nil,
|
||||
modules: [String: [String: Type]],
|
||||
typealiases: [String: Typealias],
|
||||
associatedTypes: [String: AssociatedType]
|
||||
) -> (name: String, typealias: Typealias?)? {
|
||||
// if the type exists for this name and isn't an extension just return it's name
|
||||
// if it's extension we need to check if there aren't other options TODO: verify
|
||||
if let realType = unique?[type], realType.isExtension == false {
|
||||
@@ -2427,6 +2458,13 @@ internal struct ParserResultsComposed {
|
||||
return (name: alias.type?.globalName ?? alias.typeName.name, typealias: alias)
|
||||
}
|
||||
|
||||
if let associatedType = associatedTypes[type],
|
||||
let actualType = associatedType.type
|
||||
{
|
||||
let typeName = associatedType.typeName ?? TypeName(name: actualType.name)
|
||||
return (name: actualType.globalName, typealias: Typealias(aliasName: type, typeName: typeName))
|
||||
}
|
||||
|
||||
if let containingType = containingType {
|
||||
if type == "Self" {
|
||||
return (name: containingType.globalName, typealias: nil)
|
||||
@@ -2436,7 +2474,7 @@ internal struct ParserResultsComposed {
|
||||
while currentContainer != nil, let parentName = currentContainer?.globalName {
|
||||
/// TODO: no parent for sure?
|
||||
/// manually walk the containment tree
|
||||
if let name = resolveGlobalName(for: "\\(parentName).\\(type)", containingType: nil, unique: unique, modules: modules, typealiases: typealiases) {
|
||||
if let name = resolveGlobalName(for: "\\(parentName).\\(type)", containingType: nil, unique: unique, modules: modules, typealiases: typealiases, associatedTypes: associatedTypes) {
|
||||
return name
|
||||
}
|
||||
|
||||
@@ -2770,20 +2808,27 @@ internal struct ParserResultsComposed {
|
||||
}
|
||||
}
|
||||
|
||||
return unique[resolvedIdentifier]
|
||||
if let associatedType = associatedTypes[resolvedIdentifier] {
|
||||
return associatedType.type
|
||||
}
|
||||
|
||||
return unique[resolvedIdentifier] ?? unique[typeName.name]
|
||||
}
|
||||
|
||||
private func actualTypeName(for typeName: TypeName,
|
||||
containingType: Type? = nil) -> TypeName? {
|
||||
containingType: Type? = nil) -> TypeName? {
|
||||
let unique = typeMap
|
||||
let typealiases = resolvedTypealiases
|
||||
let associatedTypes = associatedTypes
|
||||
|
||||
var unwrapped = typeName.unwrappedTypeName
|
||||
if let generic = typeName.generic {
|
||||
unwrapped = generic.name
|
||||
} else if let type = associatedTypes[unwrapped] {
|
||||
unwrapped = type.name
|
||||
}
|
||||
|
||||
guard let aliased = resolveGlobalName(for: unwrapped, containingType: containingType, unique: unique, modules: modules, typealiases: typealiases) else {
|
||||
guard let aliased = resolveGlobalName(for: unwrapped, containingType: containingType, unique: unique, modules: modules, typealiases: typealiases, associatedTypes: associatedTypes) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2862,8 +2907,11 @@ public typealias SourceryProtocol = Protocol
|
||||
#endif
|
||||
public final class Protocol: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "protocol" }
|
||||
|
||||
/// Returns "protocol"
|
||||
public override var kind: String { return "protocol" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// list of all declared associated types with their names as keys
|
||||
public var associatedTypes: [String: AssociatedType] {
|
||||
@@ -2897,7 +2945,8 @@ public final class Protocol: Type {
|
||||
modifiers: [SourceryModifier] = [],
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Protocol.kind) {
|
||||
self.associatedTypes = associatedTypes
|
||||
super.init(
|
||||
name: name,
|
||||
@@ -2916,7 +2965,8 @@ public final class Protocol: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: !associatedTypes.isEmpty || !genericRequirements.isEmpty,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2992,8 +3042,11 @@ import Foundation
|
||||
#endif
|
||||
public final class ProtocolComposition: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "protocolComposition" }
|
||||
|
||||
/// Returns "protocolComposition"
|
||||
public override var kind: String { return "protocolComposition" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// The names of the types composed to form this composition
|
||||
public let composedTypeNames: [TypeName]
|
||||
@@ -3018,7 +3071,8 @@ public final class ProtocolComposition: Type {
|
||||
isGeneric: Bool = false,
|
||||
composedTypeNames: [TypeName] = [],
|
||||
composedTypes: [Type]? = nil,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = ProtocolComposition.kind) {
|
||||
self.composedTypeNames = composedTypeNames
|
||||
self.composedTypes = composedTypes
|
||||
super.init(
|
||||
@@ -3034,7 +3088,8 @@ public final class ProtocolComposition: Type {
|
||||
typealiases: typealiases,
|
||||
annotations: annotations,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3224,8 +3279,11 @@ import Foundation
|
||||
#endif
|
||||
public final class Struct: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "struct" }
|
||||
|
||||
/// Returns "struct"
|
||||
public override var kind: String { return "struct" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// :nodoc:
|
||||
public override init(name: String = "",
|
||||
@@ -3244,7 +3302,8 @@ public final class Struct: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Struct.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -3262,7 +3321,8 @@ public final class Struct: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4238,9 +4298,13 @@ import Foundation
|
||||
/// Defines Swift enum
|
||||
@objcMembers
|
||||
public final class Enum: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "enum" }
|
||||
|
||||
// sourcery: skipDescription
|
||||
/// Returns "enum"
|
||||
public override var kind: String { return "enum" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Enum cases
|
||||
public var cases: [EnumCase]
|
||||
@@ -4312,7 +4376,7 @@ public final class Enum: Type {
|
||||
self.rawTypeName = rawTypeName
|
||||
self.hasRawType = rawTypeName != nil || !inheritedTypes.isEmpty
|
||||
|
||||
super.init(name: name, parent: parent, accessLevel: accessLevel, isExtension: isExtension, variables: variables, methods: methods, inheritedTypes: inheritedTypes, containedTypes: containedTypes, typealiases: typealiases, attributes: attributes, modifiers: modifiers, annotations: annotations, documentation: documentation, isGeneric: isGeneric)
|
||||
super.init(name: name, parent: parent, accessLevel: accessLevel, isExtension: isExtension, variables: variables, methods: methods, inheritedTypes: inheritedTypes, containedTypes: containedTypes, typealiases: typealiases, attributes: attributes, modifiers: modifiers, annotations: annotations, documentation: documentation, isGeneric: isGeneric, kind: Self.kind)
|
||||
|
||||
if let rawTypeName = rawTypeName?.name, let index = self.inheritedTypes.firstIndex(of: rawTypeName) {
|
||||
self.inheritedTypes.remove(at: index)
|
||||
@@ -6025,7 +6089,11 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
|
||||
// sourcery: forceEquality
|
||||
/// Kind of type declaration, i.e. `enum`, `struct`, `class`, `protocol` or `extension`
|
||||
public var kind: String { isExtension ? "extension" : "unknown" }
|
||||
public var kind: String { isExtension ? "extension" : _kind }
|
||||
|
||||
// sourcery: skipJSExport
|
||||
/// Kind of a backing store for `self.kind`
|
||||
private var _kind: String
|
||||
|
||||
/// Type access level, i.e. `internal`, `private`, `fileprivate`, `public`, `open`
|
||||
public let accessLevel: String
|
||||
@@ -6355,7 +6423,8 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = "unknown") {
|
||||
self.localName = name
|
||||
self.accessLevel = accessLevel.rawValue
|
||||
self.isExtension = isExtension
|
||||
@@ -6374,6 +6443,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
self.isGeneric = isGeneric
|
||||
self.genericRequirements = genericRequirements
|
||||
self.implements = implements
|
||||
self._kind = kind
|
||||
super.init()
|
||||
containedTypes.forEach {
|
||||
containedType[$0.localName] = $0
|
||||
@@ -6412,6 +6482,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
string.append("typealiases = \\(String(describing: self.typealiases)), ")
|
||||
string.append("isExtension = \\(String(describing: self.isExtension)), ")
|
||||
string.append("kind = \\(String(describing: self.kind)), ")
|
||||
string.append("_kind = \\(String(describing: self._kind)), ")
|
||||
string.append("accessLevel = \\(String(describing: self.accessLevel)), ")
|
||||
string.append("name = \\(String(describing: self.name)), ")
|
||||
string.append("isUnknownExtension = \\(String(describing: self.isUnknownExtension)), ")
|
||||
@@ -6547,6 +6618,12 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
fatalError()
|
||||
}; self.typealiases = typealiases
|
||||
self.isExtension = aDecoder.decode(forKey: "isExtension")
|
||||
guard let _kind: String = aDecoder.decode(forKey: "_kind") else {
|
||||
withVaList(["_kind"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self._kind = _kind
|
||||
guard let accessLevel: String = aDecoder.decode(forKey: "accessLevel") else {
|
||||
withVaList(["accessLevel"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
@@ -6665,6 +6742,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable {
|
||||
aCoder.encode(self.imports, forKey: "imports")
|
||||
aCoder.encode(self.typealiases, forKey: "typealiases")
|
||||
aCoder.encode(self.isExtension, forKey: "isExtension")
|
||||
aCoder.encode(self._kind, forKey: "_kind")
|
||||
aCoder.encode(self.accessLevel, forKey: "accessLevel")
|
||||
aCoder.encode(self.isGeneric, forKey: "isGeneric")
|
||||
aCoder.encode(self.localName, forKey: "localName")
|
||||
|
||||
@@ -31,8 +31,12 @@ import Foundation
|
||||
@objc(SwiftActor) @objcMembers
|
||||
#endif
|
||||
public final class Actor: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "actor" }
|
||||
|
||||
/// Returns "actor"
|
||||
public override var kind: String { return "actor" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Whether type is final
|
||||
public var isFinal: Bool {
|
||||
@@ -61,7 +65,8 @@ public final class Actor: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Actor.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -79,7 +84,8 @@ public final class Actor: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -620,8 +626,11 @@ import Foundation
|
||||
@objc(SwiftClass) @objcMembers
|
||||
#endif
|
||||
public final class Class: Type {
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "class" }
|
||||
|
||||
/// Returns "class"
|
||||
public override var kind: String { return "class" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Whether type is final
|
||||
public var isFinal: Bool {
|
||||
@@ -645,7 +654,8 @@ public final class Class: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Class.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -663,7 +673,8 @@ public final class Class: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -746,11 +757,11 @@ public enum Composer {
|
||||
let composed = ParserResultsComposed(parserResult: parserResult)
|
||||
|
||||
let resolveType = { (typeName: TypeName, containingType: Type?) -> Type? in
|
||||
return composed.resolveType(typeName: typeName, containingType: containingType)
|
||||
composed.resolveType(typeName: typeName, containingType: containingType)
|
||||
}
|
||||
|
||||
let methodResolveType = { (typeName: TypeName, containingType: Type?, method: Method) -> Type? in
|
||||
return composed.resolveType(typeName: typeName, containingType: containingType, method: method)
|
||||
composed.resolveType(typeName: typeName, containingType: containingType, method: method)
|
||||
}
|
||||
|
||||
let processType = { (type: Type) in
|
||||
@@ -773,7 +784,7 @@ public enum Composer {
|
||||
}
|
||||
|
||||
if let sourceryProtocol = type as? SourceryProtocol {
|
||||
resolveProtocolTypes(sourceryProtocol, resolve: resolveType)
|
||||
resolveAssociatedTypes(sourceryProtocol, resolve: resolveType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,11 +912,13 @@ public enum Composer {
|
||||
protocolComposition.composedTypes = composedTypes
|
||||
}
|
||||
|
||||
private static func resolveProtocolTypes(_ sourceryProtocol: SourceryProtocol, resolve: TypeResolver) {
|
||||
private static func resolveAssociatedTypes(_ sourceryProtocol: SourceryProtocol, resolve: TypeResolver) {
|
||||
sourceryProtocol.associatedTypes.forEach { (_, value) in
|
||||
guard let typeName = value.typeName,
|
||||
let type = resolve(typeName, sourceryProtocol)
|
||||
else { return }
|
||||
else {
|
||||
return
|
||||
}
|
||||
value.type = type
|
||||
}
|
||||
|
||||
@@ -2218,6 +2231,7 @@ internal struct ParserResultsComposed {
|
||||
let parsedTypes: [Type]
|
||||
let functions: [SourceryMethod]
|
||||
let resolvedTypealiases: [String: Typealias]
|
||||
let associatedTypes: [String: AssociatedType]
|
||||
let unresolvedTypealiases: [String: Typealias]
|
||||
|
||||
init(parserResult: FileParserResult) {
|
||||
@@ -2228,6 +2242,7 @@ internal struct ParserResultsComposed {
|
||||
let aliases = Self.typealiases(parserResult)
|
||||
resolvedTypealiases = aliases.resolved
|
||||
unresolvedTypealiases = aliases.unresolved
|
||||
associatedTypes = Self.extractAssociatedTypes(parserResult)
|
||||
parsedTypes = parserResult.types
|
||||
|
||||
// set definedInType for all methods and variables
|
||||
@@ -2256,6 +2271,11 @@ internal struct ParserResultsComposed {
|
||||
alias.type = resolveType(typeName: alias.typeName, containingType: alias.parent)
|
||||
}
|
||||
|
||||
/// Map associated types
|
||||
associatedTypes.forEach {
|
||||
typeMap[$0.key] = $0.value.type
|
||||
}
|
||||
|
||||
types = unifyTypes()
|
||||
}
|
||||
|
||||
@@ -2301,7 +2321,7 @@ internal struct ParserResultsComposed {
|
||||
resolveExtensionOfNestedType(type)
|
||||
}
|
||||
|
||||
if let resolved = resolveGlobalName(for: oldName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases)?.name {
|
||||
if let resolved = resolveGlobalName(for: oldName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases, associatedTypes: associatedTypes)?.name {
|
||||
var moduleName: String = ""
|
||||
if let module = type.module {
|
||||
moduleName = "\\(module)."
|
||||
@@ -2321,7 +2341,7 @@ internal struct ParserResultsComposed {
|
||||
// extend all types with their extensions
|
||||
parsedTypes.forEach { type in
|
||||
let inheritedTypes: [[String]] = type.inheritedTypes.compactMap { inheritedName in
|
||||
if let resolvedGlobalName = resolveGlobalName(for: inheritedName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases)?.name {
|
||||
if let resolvedGlobalName = resolveGlobalName(for: inheritedName, containingType: type.parent, unique: typeMap, modules: modules, typealiases: resolvedTypealiases, associatedTypes: associatedTypes)?.name {
|
||||
return [resolvedGlobalName]
|
||||
}
|
||||
if let baseType = Composer.findBaseType(for: type, name: inheritedName, typesByName: typeMap) {
|
||||
@@ -2380,6 +2400,14 @@ internal struct ParserResultsComposed {
|
||||
})
|
||||
}
|
||||
|
||||
// extract associated types from all types and add them to types
|
||||
private static func extractAssociatedTypes(_ parserResult: FileParserResult) -> [String: AssociatedType] {
|
||||
parserResult.types
|
||||
.compactMap { $0 as? SourceryProtocol }
|
||||
.map { $0.associatedTypes }
|
||||
.flatMap { $0 }.reduce(into: [:]) { $0[$1.key] = $1.value }
|
||||
}
|
||||
|
||||
/// returns typealiases map to their full names, with `resolved` removing intermediate
|
||||
/// typealises and `unresolved` including typealiases that reference other typealiases.
|
||||
private static func typealiases(_ parserResult: FileParserResult) -> (resolved: [String: Typealias], unresolved: [String: Typealias]) {
|
||||
@@ -2412,11 +2440,14 @@ internal struct ParserResultsComposed {
|
||||
}
|
||||
|
||||
/// Resolves type identifier for name
|
||||
func resolveGlobalName(for type: String,
|
||||
containingType: Type? = nil,
|
||||
unique: [String: Type]? = nil,
|
||||
modules: [String: [String: Type]],
|
||||
typealiases: [String: Typealias]) -> (name: String, typealias: Typealias?)? {
|
||||
func resolveGlobalName(
|
||||
for type: String,
|
||||
containingType: Type? = nil,
|
||||
unique: [String: Type]? = nil,
|
||||
modules: [String: [String: Type]],
|
||||
typealiases: [String: Typealias],
|
||||
associatedTypes: [String: AssociatedType]
|
||||
) -> (name: String, typealias: Typealias?)? {
|
||||
// if the type exists for this name and isn't an extension just return it's name
|
||||
// if it's extension we need to check if there aren't other options TODO: verify
|
||||
if let realType = unique?[type], realType.isExtension == false {
|
||||
@@ -2427,6 +2458,13 @@ internal struct ParserResultsComposed {
|
||||
return (name: alias.type?.globalName ?? alias.typeName.name, typealias: alias)
|
||||
}
|
||||
|
||||
if let associatedType = associatedTypes[type],
|
||||
let actualType = associatedType.type
|
||||
{
|
||||
let typeName = associatedType.typeName ?? TypeName(name: actualType.name)
|
||||
return (name: actualType.globalName, typealias: Typealias(aliasName: type, typeName: typeName))
|
||||
}
|
||||
|
||||
if let containingType = containingType {
|
||||
if type == "Self" {
|
||||
return (name: containingType.globalName, typealias: nil)
|
||||
@@ -2436,7 +2474,7 @@ internal struct ParserResultsComposed {
|
||||
while currentContainer != nil, let parentName = currentContainer?.globalName {
|
||||
/// TODO: no parent for sure?
|
||||
/// manually walk the containment tree
|
||||
if let name = resolveGlobalName(for: "\\(parentName).\\(type)", containingType: nil, unique: unique, modules: modules, typealiases: typealiases) {
|
||||
if let name = resolveGlobalName(for: "\\(parentName).\\(type)", containingType: nil, unique: unique, modules: modules, typealiases: typealiases, associatedTypes: associatedTypes) {
|
||||
return name
|
||||
}
|
||||
|
||||
@@ -2770,20 +2808,27 @@ internal struct ParserResultsComposed {
|
||||
}
|
||||
}
|
||||
|
||||
return unique[resolvedIdentifier]
|
||||
if let associatedType = associatedTypes[resolvedIdentifier] {
|
||||
return associatedType.type
|
||||
}
|
||||
|
||||
return unique[resolvedIdentifier] ?? unique[typeName.name]
|
||||
}
|
||||
|
||||
private func actualTypeName(for typeName: TypeName,
|
||||
containingType: Type? = nil) -> TypeName? {
|
||||
containingType: Type? = nil) -> TypeName? {
|
||||
let unique = typeMap
|
||||
let typealiases = resolvedTypealiases
|
||||
let associatedTypes = associatedTypes
|
||||
|
||||
var unwrapped = typeName.unwrappedTypeName
|
||||
if let generic = typeName.generic {
|
||||
unwrapped = generic.name
|
||||
} else if let type = associatedTypes[unwrapped] {
|
||||
unwrapped = type.name
|
||||
}
|
||||
|
||||
guard let aliased = resolveGlobalName(for: unwrapped, containingType: containingType, unique: unique, modules: modules, typealiases: typealiases) else {
|
||||
guard let aliased = resolveGlobalName(for: unwrapped, containingType: containingType, unique: unique, modules: modules, typealiases: typealiases, associatedTypes: associatedTypes) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2862,8 +2907,11 @@ public typealias SourceryProtocol = Protocol
|
||||
#endif
|
||||
public final class Protocol: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "protocol" }
|
||||
|
||||
/// Returns "protocol"
|
||||
public override var kind: String { return "protocol" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// list of all declared associated types with their names as keys
|
||||
public var associatedTypes: [String: AssociatedType] {
|
||||
@@ -2897,7 +2945,8 @@ public final class Protocol: Type {
|
||||
modifiers: [SourceryModifier] = [],
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Protocol.kind) {
|
||||
self.associatedTypes = associatedTypes
|
||||
super.init(
|
||||
name: name,
|
||||
@@ -2916,7 +2965,8 @@ public final class Protocol: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: !associatedTypes.isEmpty || !genericRequirements.isEmpty,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2992,8 +3042,11 @@ import Foundation
|
||||
#endif
|
||||
public final class ProtocolComposition: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "protocolComposition" }
|
||||
|
||||
/// Returns "protocolComposition"
|
||||
public override var kind: String { return "protocolComposition" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// The names of the types composed to form this composition
|
||||
public let composedTypeNames: [TypeName]
|
||||
@@ -3018,7 +3071,8 @@ public final class ProtocolComposition: Type {
|
||||
isGeneric: Bool = false,
|
||||
composedTypeNames: [TypeName] = [],
|
||||
composedTypes: [Type]? = nil,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = ProtocolComposition.kind) {
|
||||
self.composedTypeNames = composedTypeNames
|
||||
self.composedTypes = composedTypes
|
||||
super.init(
|
||||
@@ -3034,7 +3088,8 @@ public final class ProtocolComposition: Type {
|
||||
typealiases: typealiases,
|
||||
annotations: annotations,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3224,8 +3279,11 @@ import Foundation
|
||||
#endif
|
||||
public final class Struct: Type {
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "struct" }
|
||||
|
||||
/// Returns "struct"
|
||||
public override var kind: String { return "struct" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// :nodoc:
|
||||
public override init(name: String = "",
|
||||
@@ -3244,7 +3302,8 @@ public final class Struct: Type {
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = Struct.kind) {
|
||||
super.init(
|
||||
name: name,
|
||||
parent: parent,
|
||||
@@ -3262,7 +3321,8 @@ public final class Struct: Type {
|
||||
annotations: annotations,
|
||||
documentation: documentation,
|
||||
isGeneric: isGeneric,
|
||||
implements: implements
|
||||
implements: implements,
|
||||
kind: kind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4531,9 +4591,12 @@ public final class Enum: Type {
|
||||
}
|
||||
}
|
||||
|
||||
// sourcery: skipJSExport
|
||||
public class var kind: String { return "enum" }
|
||||
|
||||
// sourcery: skipDescription
|
||||
/// Returns "enum"
|
||||
public override var kind: String { return "enum" }
|
||||
public override var kind: String { Self.kind }
|
||||
|
||||
/// Enum cases
|
||||
public var cases: [EnumCase]
|
||||
@@ -4605,7 +4668,7 @@ public final class Enum: Type {
|
||||
self.rawTypeName = rawTypeName
|
||||
self.hasRawType = rawTypeName != nil || !inheritedTypes.isEmpty
|
||||
|
||||
super.init(name: name, parent: parent, accessLevel: accessLevel, isExtension: isExtension, variables: variables, methods: methods, inheritedTypes: inheritedTypes, containedTypes: containedTypes, typealiases: typealiases, attributes: attributes, modifiers: modifiers, annotations: annotations, documentation: documentation, isGeneric: isGeneric)
|
||||
super.init(name: name, parent: parent, accessLevel: accessLevel, isExtension: isExtension, variables: variables, methods: methods, inheritedTypes: inheritedTypes, containedTypes: containedTypes, typealiases: typealiases, attributes: attributes, modifiers: modifiers, annotations: annotations, documentation: documentation, isGeneric: isGeneric, kind: Self.kind)
|
||||
|
||||
if let rawTypeName = rawTypeName?.name, let index = self.inheritedTypes.firstIndex(of: rawTypeName) {
|
||||
self.inheritedTypes.remove(at: index)
|
||||
@@ -6734,7 +6797,11 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
|
||||
// sourcery: forceEquality
|
||||
/// Kind of type declaration, i.e. `enum`, `struct`, `class`, `protocol` or `extension`
|
||||
public var kind: String { isExtension ? "extension" : "unknown" }
|
||||
public var kind: String { isExtension ? "extension" : _kind }
|
||||
|
||||
// sourcery: skipJSExport
|
||||
/// Kind of a backing store for `self.kind`
|
||||
private var _kind: String
|
||||
|
||||
/// Type access level, i.e. `internal`, `private`, `fileprivate`, `public`, `open`
|
||||
public let accessLevel: String
|
||||
@@ -7064,7 +7131,8 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
annotations: [String: NSObject] = [:],
|
||||
documentation: [String] = [],
|
||||
isGeneric: Bool = false,
|
||||
implements: [String: Type] = [:]) {
|
||||
implements: [String: Type] = [:],
|
||||
kind: String = "unknown") {
|
||||
self.localName = name
|
||||
self.accessLevel = accessLevel.rawValue
|
||||
self.isExtension = isExtension
|
||||
@@ -7083,6 +7151,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
self.isGeneric = isGeneric
|
||||
self.genericRequirements = genericRequirements
|
||||
self.implements = implements
|
||||
self._kind = kind
|
||||
super.init()
|
||||
containedTypes.forEach {
|
||||
containedType[$0.localName] = $0
|
||||
@@ -7113,13 +7182,15 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
/// :nodoc:
|
||||
// sourcery: skipJSExport
|
||||
override public var description: String {
|
||||
var string = "\\(Swift.type(of: self)): "
|
||||
let type: Type.Type = Swift.type(of: self)
|
||||
var string = "\\(type): "
|
||||
string.append("module = \\(String(describing: self.module)), ")
|
||||
string.append("imports = \\(String(describing: self.imports)), ")
|
||||
string.append("allImports = \\(String(describing: self.allImports)), ")
|
||||
string.append("typealiases = \\(String(describing: self.typealiases)), ")
|
||||
string.append("isExtension = \\(String(describing: self.isExtension)), ")
|
||||
string.append("kind = \\(String(describing: self.kind)), ")
|
||||
string.append("_kind = \\(String(describing: self._kind)), ")
|
||||
string.append("accessLevel = \\(String(describing: self.accessLevel)), ")
|
||||
string.append("name = \\(String(describing: self.name)), ")
|
||||
string.append("isUnknownExtension = \\(String(describing: self.isUnknownExtension)), ")
|
||||
@@ -7255,6 +7326,12 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
fatalError()
|
||||
}; self.typealiases = typealiases
|
||||
self.isExtension = aDecoder.decode(forKey: "isExtension")
|
||||
guard let _kind: String = aDecoder.decode(forKey: "_kind") else {
|
||||
withVaList(["_kind"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
}
|
||||
fatalError()
|
||||
}; self._kind = _kind
|
||||
guard let accessLevel: String = aDecoder.decode(forKey: "accessLevel") else {
|
||||
withVaList(["accessLevel"]) { arguments in
|
||||
NSException.raise(NSExceptionName.parseErrorException, format: "Key '%@' not found.", arguments: arguments)
|
||||
@@ -7373,6 +7450,7 @@ public class Type: NSObject, SourceryModel, Annotated, Documented, Diffable, Sou
|
||||
aCoder.encode(self.imports, forKey: "imports")
|
||||
aCoder.encode(self.typealiases, forKey: "typealiases")
|
||||
aCoder.encode(self.isExtension, forKey: "isExtension")
|
||||
aCoder.encode(self._kind, forKey: "_kind")
|
||||
aCoder.encode(self.accessLevel, forKey: "accessLevel")
|
||||
aCoder.encode(self.isGeneric, forKey: "isGeneric")
|
||||
aCoder.encode(self.localName, forKey: "localName")
|
||||
|
||||
@@ -485,15 +485,6 @@ internal func == (lhs: EqEnum, rhs: EqEnum) -> Bool {
|
||||
let outputInterceptor = OutputInterceptor()
|
||||
sourcery.dryOutput = outputInterceptor.handleOutput(_:)
|
||||
|
||||
let expectedResults = ["Basic+Other.swift",
|
||||
"Basic.swift",
|
||||
"Basic+Other.swift",
|
||||
"Basic.swift",
|
||||
"Basic.swift",
|
||||
"Basic.swift",
|
||||
"Function.swift"]
|
||||
.compactMap { try? (Stubs.resultDirectory + Path($0)).read(.utf8) }
|
||||
|
||||
expect {
|
||||
try sourcery.processFiles(.sources(Paths(include: [Stubs.sourceDirectory])),
|
||||
usingTemplates: Paths(include: templatePaths),
|
||||
|
||||
@@ -1793,7 +1793,7 @@ class ParserComposerSpec: QuickSpec {
|
||||
actualTypeName: givenTypealias.typeName
|
||||
)
|
||||
)
|
||||
let actualProtocol = parse(code).first
|
||||
let actualProtocol = parse(code).last
|
||||
expect(actualProtocol).to(equal(expectedProtocol))
|
||||
let actualTypeName = (actualProtocol as? SourceryProtocol)?.associatedTypes.first?.value.typeName?.actualTypeName
|
||||
expect(actualTypeName).to(equal(givenTypealias.actualTypeName))
|
||||
@@ -1902,7 +1902,7 @@ class ParserComposerSpec: QuickSpec {
|
||||
|
||||
it("resolves protocol generic requirement types and inherits associated types") {
|
||||
let expectedRightType = Struct(name: "RightType")
|
||||
let genericProtocol = Protocol(name: "GenericProtocol", associatedTypes: ["LeftType": AssociatedType(name: "LeftType")])
|
||||
let genericProtocol = Protocol(name: "GenericProtocol", associatedTypes: ["LeftType": AssociatedType(name: "LeftType", typeName: TypeName(name: "Any"))])
|
||||
let expectedProtocol = Protocol(name: "SomeGenericProtocol", inheritedTypes: ["GenericProtocol"])
|
||||
expectedProtocol.associatedTypes = genericProtocol.associatedTypes
|
||||
expectedProtocol.genericRequirements = [
|
||||
|
||||
@@ -33,7 +33,7 @@ final class FileParserAssociatedTypeSpec: QuickSpec {
|
||||
associatedtype Bar
|
||||
}
|
||||
"""
|
||||
expect(associatedType(code)).to(equal([AssociatedType(name: "Bar")]))
|
||||
expect(associatedType(code)).to(equal([AssociatedType(name: "Bar", typeName: TypeName(name: "Any"))]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ final class FileParserAssociatedTypeSpec: QuickSpec {
|
||||
associatedtype Baz
|
||||
}
|
||||
"""
|
||||
expect(associatedType(code).sorted(by: { $0.name < $1.name })).to(equal([AssociatedType(name: "Bar"), AssociatedType(name: "Baz")]))
|
||||
expect(associatedType(code).sorted(by: { $0.name < $1.name })).to(equal([AssociatedType(name: "Bar", typeName: TypeName(name: "Any")), AssociatedType(name: "Baz", typeName: TypeName(name: "Any"))]))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ var variable: Bool
|
||||
expect(arguments).toNot(beNil())
|
||||
if let parsedArguments = arguments {
|
||||
for expected in expectedArguments {
|
||||
expect((parsedArguments[expected.key] as? NSObject)).to(equal(expected.value))
|
||||
expect(parsedArguments[expected.key]).to(equal(expected.value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,8 +332,50 @@ import {{ import }}
|
||||
{%- endmacro %}
|
||||
{% macro methodName method %}func {{ method.shortName}}({%- for param in method.parameters %}{% if param.argumentLabel == nil %}_ {% if not param.name == "" %}{{ param.name }}{% else %}arg{{ param.index }}{% endif %}{%elif param.argumentLabel == param.name%}{{ param.name }}{%else%}{{ param.argumentLabel }} {{ param.name }}{% endif %}: {% if param.typeName.isClosure and param.typeName.closure.parameters.count > 1 %}({% endif %}{% call existentialParameterTypeName param.typeName param.isVariadic %}{% if not forloop.last %}, {% endif %}{% endfor -%}){% endmacro %}
|
||||
|
||||
{% macro extractProtocolCompositionFromAssociatedTypes type -%}
|
||||
{%- if type.associatedTypes|sortedValuesByKeys|count > 0 -%}
|
||||
<
|
||||
{%- for associatedType in type.associatedTypes|sortedValuesByKeys -%}
|
||||
{% if associatedType.type.kind != nil and associatedType.type.kind|contains:"protocol" %}
|
||||
{{ associatedType.name }}: {{ associatedType.typeName }},
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
>
|
||||
{%- endif -%}
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro extractProtocolRequirementsFromAssociatedTypes associatedTypes -%}
|
||||
{%- for associatedType in associatedTypes -%}
|
||||
{%- if associatedType.type.kind != nil and associatedType.type.kind|contains:"protocol" -%}
|
||||
{%- for requirement in associatedType.type.genericRequirements -%}
|
||||
{%- set requirementString -%}
|
||||
{{ requirement.leftType.name }} {{ requirement.relationshipSyntax }} {{ requirement.rightType.typeName.name }}
|
||||
{%- endset -%}
|
||||
{{ requirementString }},
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
|
||||
{% macro extractProtocolRequirementsFromType type -%}
|
||||
{%- set requirements -%}
|
||||
{% call extractProtocolRequirementsFromAssociatedTypes type.associatedTypes|sortedValuesByKeys %}
|
||||
{%- endset -%}
|
||||
{% if requirements|isEmpty == false %}
|
||||
where {{ requirements }}{
|
||||
{%- else -%}
|
||||
{
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% for type in types.protocols where type.based.AutoMockable or type|annotated:"AutoMockable" %}{% if type.name != "AutoMockable" %}
|
||||
{% call accessLevel type.accessLevel %}class {{ type.name }}Mock: {{ type.name }} {
|
||||
{% call accessLevel type.accessLevel %}class {{ type.name }}Mock{% set generics %}{% call extractProtocolCompositionFromAssociatedTypes type %}{% endset %}{{ generics | replace:",>",">"}}: {{ type.name }} {%- set requirements -%}{% call extractProtocolRequirementsFromType type %}{%- endset -%} {{ requirements|replace:",{","{"|replace:"{"," {" }}
|
||||
{% for associatedType in type.associatedTypes|sortedValuesByKeys %}
|
||||
{% if associatedType.type.kind == nil or not associatedType.type.kind|contains:"protocol" %}
|
||||
typealias {{ associatedType.name }} = {% if associatedType.type != nil %}{{ associatedType.type.name }}{% elif associatedType.typeName != nil %}{{ associatedType.typeName.name }}{% else %}Any{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if type.accessLevel == "public" %}public init() {}{% endif %}
|
||||
|
||||
|
||||
@@ -270,3 +270,25 @@ public protocol ProtocolWithMethodWithInoutParameter {
|
||||
func execute(param: inout String)
|
||||
func execute(param: inout String, bar: Int)
|
||||
}
|
||||
//sourcery:AutoMockable
|
||||
protocol TestProtocol {
|
||||
associatedtype Value: Sequence where Value.Element: Collection, Value.Element: Hashable, Value.Element: Comparable
|
||||
|
||||
func getValue() -> Value
|
||||
|
||||
associatedtype Value2 = Int
|
||||
|
||||
func getValue2() -> Value2
|
||||
|
||||
associatedtype Value3: Collection where Value3.Element == String
|
||||
|
||||
func getValue3() -> Value3
|
||||
|
||||
associatedtype Value5: Sequence where Value5.Element == Int
|
||||
|
||||
func getValue5() -> Value5
|
||||
|
||||
associatedtype Value6: Sequence where Value6.Element == Int, Value6.Element: Hashable, Value6.Element: Comparable
|
||||
|
||||
func getValue6() -> Value6
|
||||
}
|
||||
|
||||
@@ -270,3 +270,25 @@ public protocol ProtocolWithMethodWithInoutParameter {
|
||||
func execute(param: inout String)
|
||||
func execute(param: inout String, bar: Int)
|
||||
}
|
||||
//sourcery:AutoMockable
|
||||
protocol TestProtocol {
|
||||
associatedtype Value: Sequence where Value.Element: Collection, Value.Element: Hashable, Value.Element: Comparable
|
||||
|
||||
func getValue() -> Value
|
||||
|
||||
associatedtype Value2 = Int
|
||||
|
||||
func getValue2() -> Value2
|
||||
|
||||
associatedtype Value3: Collection where Value3.Element == String
|
||||
|
||||
func getValue3() -> Value3
|
||||
|
||||
associatedtype Value5: Sequence where Value5.Element == Int
|
||||
|
||||
func getValue5() -> Value5
|
||||
|
||||
associatedtype Value6: Sequence where Value6.Element == Int, Value6.Element: Hashable, Value6.Element: Comparable
|
||||
|
||||
func getValue6() -> Value6
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 2.2.4 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
// swiftlint:disable line_length
|
||||
// swiftlint:disable variable_name
|
||||
@@ -31,6 +31,7 @@ import AppKit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class AccessLevelProtocolMock: AccessLevelProtocol {
|
||||
@@ -1644,6 +1645,109 @@ class SubscriptProtocolMock: SubscriptProtocol {
|
||||
subscript<T>(arg: String) -> T? where T : Cancellable {
|
||||
get throws { fatalError("Subscripts are not fully supported yet") }
|
||||
}
|
||||
}
|
||||
class TestProtocolMock<
|
||||
Value: Sequence,
|
||||
Value3: Collection,
|
||||
Value5: Sequence,
|
||||
Value6: Sequence>: TestProtocol
|
||||
where Value.Element : Collection,Value.Element : Hashable,Value.Element : Comparable,Value3.Element == String,Value5.Element == Int,Value6.Element == Int,Value6.Element : Hashable,Value6.Element : Comparable {
|
||||
typealias Value2 = Int
|
||||
|
||||
|
||||
|
||||
|
||||
//MARK: - getValue
|
||||
|
||||
var getValueSequenceCallsCount = 0
|
||||
var getValueSequenceCalled: Bool {
|
||||
return getValueSequenceCallsCount > 0
|
||||
}
|
||||
var getValueSequenceReturnValue: Value!
|
||||
var getValueSequenceClosure: (() -> Value)?
|
||||
|
||||
func getValue() -> Value {
|
||||
getValueSequenceCallsCount += 1
|
||||
if let getValueSequenceClosure = getValueSequenceClosure {
|
||||
return getValueSequenceClosure()
|
||||
} else {
|
||||
return getValueSequenceReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - getValue2
|
||||
|
||||
var getValue2Value2CallsCount = 0
|
||||
var getValue2Value2Called: Bool {
|
||||
return getValue2Value2CallsCount > 0
|
||||
}
|
||||
var getValue2Value2ReturnValue: Value2!
|
||||
var getValue2Value2Closure: (() -> Value2)?
|
||||
|
||||
func getValue2() -> Value2 {
|
||||
getValue2Value2CallsCount += 1
|
||||
if let getValue2Value2Closure = getValue2Value2Closure {
|
||||
return getValue2Value2Closure()
|
||||
} else {
|
||||
return getValue2Value2ReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - getValue3
|
||||
|
||||
var getValue3CollectionCallsCount = 0
|
||||
var getValue3CollectionCalled: Bool {
|
||||
return getValue3CollectionCallsCount > 0
|
||||
}
|
||||
var getValue3CollectionReturnValue: Value3!
|
||||
var getValue3CollectionClosure: (() -> Value3)?
|
||||
|
||||
func getValue3() -> Value3 {
|
||||
getValue3CollectionCallsCount += 1
|
||||
if let getValue3CollectionClosure = getValue3CollectionClosure {
|
||||
return getValue3CollectionClosure()
|
||||
} else {
|
||||
return getValue3CollectionReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - getValue5
|
||||
|
||||
var getValue5SequenceCallsCount = 0
|
||||
var getValue5SequenceCalled: Bool {
|
||||
return getValue5SequenceCallsCount > 0
|
||||
}
|
||||
var getValue5SequenceReturnValue: Value5!
|
||||
var getValue5SequenceClosure: (() -> Value5)?
|
||||
|
||||
func getValue5() -> Value5 {
|
||||
getValue5SequenceCallsCount += 1
|
||||
if let getValue5SequenceClosure = getValue5SequenceClosure {
|
||||
return getValue5SequenceClosure()
|
||||
} else {
|
||||
return getValue5SequenceReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - getValue6
|
||||
|
||||
var getValue6SequenceCallsCount = 0
|
||||
var getValue6SequenceCalled: Bool {
|
||||
return getValue6SequenceCallsCount > 0
|
||||
}
|
||||
var getValue6SequenceReturnValue: Value6!
|
||||
var getValue6SequenceClosure: (() -> Value6)?
|
||||
|
||||
func getValue6() -> Value6 {
|
||||
getValue6SequenceCallsCount += 1
|
||||
if let getValue6SequenceClosure = getValue6SequenceClosure {
|
||||
return getValue6SequenceClosure()
|
||||
} else {
|
||||
return getValue6SequenceReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
class ThrowableProtocolMock: ThrowableProtocol {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 2.2.4 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
// swiftlint:disable line_length
|
||||
// swiftlint:disable variable_name
|
||||
@@ -31,6 +31,7 @@ import AppKit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class AccessLevelProtocolMock: AccessLevelProtocol {
|
||||
@@ -1644,6 +1645,109 @@ class SubscriptProtocolMock: SubscriptProtocol {
|
||||
subscript<T>(arg: String) -> T? where T : Cancellable {
|
||||
get throws { fatalError("Subscripts are not fully supported yet") }
|
||||
}
|
||||
}
|
||||
class TestProtocolMock<
|
||||
Value: Sequence,
|
||||
Value3: Collection,
|
||||
Value5: Sequence,
|
||||
Value6: Sequence>: TestProtocol
|
||||
where Value.Element : Collection,Value.Element : Hashable,Value.Element : Comparable,Value3.Element == String,Value5.Element == Int,Value6.Element == Int,Value6.Element : Hashable,Value6.Element : Comparable {
|
||||
typealias Value2 = Int
|
||||
|
||||
|
||||
|
||||
|
||||
//MARK: - getValue
|
||||
|
||||
var getValueSequenceCallsCount = 0
|
||||
var getValueSequenceCalled: Bool {
|
||||
return getValueSequenceCallsCount > 0
|
||||
}
|
||||
var getValueSequenceReturnValue: Value!
|
||||
var getValueSequenceClosure: (() -> Value)?
|
||||
|
||||
func getValue() -> Value {
|
||||
getValueSequenceCallsCount += 1
|
||||
if let getValueSequenceClosure = getValueSequenceClosure {
|
||||
return getValueSequenceClosure()
|
||||
} else {
|
||||
return getValueSequenceReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - getValue2
|
||||
|
||||
var getValue2Value2CallsCount = 0
|
||||
var getValue2Value2Called: Bool {
|
||||
return getValue2Value2CallsCount > 0
|
||||
}
|
||||
var getValue2Value2ReturnValue: Value2!
|
||||
var getValue2Value2Closure: (() -> Value2)?
|
||||
|
||||
func getValue2() -> Value2 {
|
||||
getValue2Value2CallsCount += 1
|
||||
if let getValue2Value2Closure = getValue2Value2Closure {
|
||||
return getValue2Value2Closure()
|
||||
} else {
|
||||
return getValue2Value2ReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - getValue3
|
||||
|
||||
var getValue3CollectionCallsCount = 0
|
||||
var getValue3CollectionCalled: Bool {
|
||||
return getValue3CollectionCallsCount > 0
|
||||
}
|
||||
var getValue3CollectionReturnValue: Value3!
|
||||
var getValue3CollectionClosure: (() -> Value3)?
|
||||
|
||||
func getValue3() -> Value3 {
|
||||
getValue3CollectionCallsCount += 1
|
||||
if let getValue3CollectionClosure = getValue3CollectionClosure {
|
||||
return getValue3CollectionClosure()
|
||||
} else {
|
||||
return getValue3CollectionReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - getValue5
|
||||
|
||||
var getValue5SequenceCallsCount = 0
|
||||
var getValue5SequenceCalled: Bool {
|
||||
return getValue5SequenceCallsCount > 0
|
||||
}
|
||||
var getValue5SequenceReturnValue: Value5!
|
||||
var getValue5SequenceClosure: (() -> Value5)?
|
||||
|
||||
func getValue5() -> Value5 {
|
||||
getValue5SequenceCallsCount += 1
|
||||
if let getValue5SequenceClosure = getValue5SequenceClosure {
|
||||
return getValue5SequenceClosure()
|
||||
} else {
|
||||
return getValue5SequenceReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - getValue6
|
||||
|
||||
var getValue6SequenceCallsCount = 0
|
||||
var getValue6SequenceCalled: Bool {
|
||||
return getValue6SequenceCallsCount > 0
|
||||
}
|
||||
var getValue6SequenceReturnValue: Value6!
|
||||
var getValue6SequenceClosure: (() -> Value6)?
|
||||
|
||||
func getValue6() -> Value6 {
|
||||
getValue6SequenceCallsCount += 1
|
||||
if let getValue6SequenceClosure = getValue6SequenceClosure {
|
||||
return getValue6SequenceClosure()
|
||||
} else {
|
||||
return getValue6SequenceReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
class ThrowableProtocolMock: ThrowableProtocol {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user