diff --git a/Generator/Source/CuckooGeneratorFramework/Generator.swift b/Generator/Source/CuckooGeneratorFramework/Generator.swift index ba82798..c87cc3f 100644 --- a/Generator/Source/CuckooGeneratorFramework/Generator.swift +++ b/Generator/Source/CuckooGeneratorFramework/Generator.swift @@ -112,6 +112,7 @@ public struct Generator { if parameter.isClosure && !parameter.isEscaping { let indents = String(repeating: "\t", count: index) let tries = method.isThrowing ? "try " : "" + let sugarizedReturnType = method.returnType.sugarized let returnSignature: String if sugarizedReturnType.isEmpty { @@ -123,6 +124,7 @@ public struct Generator { fullString += "\(indents)return \(tries)withoutActuallyEscaping(\(parameter.name), do: { (\(parameter.name): @escaping \(parameter.type))\(returnSignature) in\n" } } + return fullString } diff --git a/Generator/Source/CuckooGeneratorFramework/Tokens/Method.swift b/Generator/Source/CuckooGeneratorFramework/Tokens/Method.swift index 0017c1c..a85c910 100644 --- a/Generator/Source/CuckooGeneratorFramework/Tokens/Method.swift +++ b/Generator/Source/CuckooGeneratorFramework/Tokens/Method.swift @@ -6,6 +6,8 @@ // Copyright © 2016 Brightify. All rights reserved. // +import Foundation + public protocol Method: Token, HasAccessibility { var name: String { get } var returnSignature: ReturnSignature { get } @@ -79,36 +81,22 @@ public extension Method { }.joined(separator: ", ") let stubFunctionPrefix = isOverriding ? "Class" : "Protocol" - let stubFunction: String - if isThrowing { - if returnType.sugarized == "Void" { - stubFunction = "Cuckoo.\(stubFunctionPrefix)StubNoReturnThrowingFunction" - } else { - stubFunction = "Cuckoo.\(stubFunctionPrefix)StubThrowingFunction" - } - } else { - if returnType.sugarized == "Void" { - stubFunction = "Cuckoo.\(stubFunctionPrefix)StubNoReturnFunction" - } else { - stubFunction = "Cuckoo.\(stubFunctionPrefix)StubFunction" - } - } + let returnString = returnType.sugarized == "Void" ? "NoReturn" : "" + let throwingString = isThrowing ? "Throwing" : "" + let stubFunction = "Cuckoo.\(stubFunctionPrefix)Stub\(returnString)\(throwingString)Function" let escapingParameterNames = parameters.map { parameter in if parameter.isClosure && !parameter.isEscaping { let parameterCount = parameter.closureParamCount let parameterSignature = parameterCount > 0 ? (1...parameterCount).map { _ in "_" }.joined(separator: ", ") : "()" - var returnSignature = "" - if !parameter.type.sugarized.isEmpty { - returnSignature = extractClosureReturnType(parameter: parameter.type.sugarized) ?? "" - if !returnSignature.isEmpty { - if returnSignature != "Void" { - returnSignature = " -> " + returnSignature - } else { - returnSignature = "" - } - } + // FIXME: Instead of parsing the closure return type here, Tokenizer should do it and pass the information in a data structure + let returnSignature: String + let closureReturnType = extractClosureReturnType(parameter: parameter.type.sugarized) + if let closureReturnType = closureReturnType, !closureReturnType.isEmpty && closureReturnType != "Void" { + returnSignature = " -> " + closureReturnType + } else { + returnSignature = "" } return "{ \(parameterSignature)\(returnSignature) in fatalError(\"This is a stub! It's not supposed to be called!\") }" } else { @@ -128,7 +116,7 @@ public extension Method { "parameterNames": parameters.map { $0.name }.joined(separator: ", "), "escapingParameterNames": escapingParameterNames, "isInit": isInit, - "returnType": returnType.sugarizedExplicitOnly, + "returnType": returnType.explicitOptionalOnly.sugarized, "isThrowing": isThrowing, "throwType": returnSignature.throwType?.description ?? "", "fullyQualifiedName": fullyQualifiedName, @@ -146,25 +134,25 @@ public extension Method { "genericParameters": isGeneric ? "<\(genericParametersString)>" : "", ] } + private func extractClosureReturnType(parameter: String) -> String? { - var parentLevel = 0 + var parenLevel = 0 for i in 0..\\s*(.*)\\s*").first - } catch let error { - fatalError("Invalid regex:" + error.localizedDescription) - } + let character = parameter[index] + if character == "(" { + parenLevel += 1 + } else if character == ")" { + parenLevel -= 1 + if parenLevel == 0 { + let returnSignature = String(parameter[parameter.index(after: index)..\\s*(.*)\\s*") + guard let result = regex.matches(in: returnSignature, range: NSRange(location: 0, length: returnSignature.count)).first else { return nil } + return returnSignature[result.range(at: 1)] } } } + return nil } } diff --git a/Generator/Source/CuckooGeneratorFramework/Tokens/ReturnSignature.swift b/Generator/Source/CuckooGeneratorFramework/Tokens/ReturnSignature.swift index 620f5ae..bf0b16c 100644 --- a/Generator/Source/CuckooGeneratorFramework/Tokens/ReturnSignature.swift +++ b/Generator/Source/CuckooGeneratorFramework/Tokens/ReturnSignature.swift @@ -25,7 +25,7 @@ public struct ReturnSignature { extension ReturnSignature: CustomStringConvertible { public var description: String { - let trimmedReturnType = returnType.sugarizedExplicitOnly.trimmed + let trimmedReturnType = returnType.explicitOptionalOnly.sugarized.trimmed let returnString = trimmedReturnType.isEmpty || trimmedReturnType == "Void" ? nil : "-> \(returnType)" let whereString = whereConstraints.isEmpty ? nil : "where \(whereConstraints.joined(separator: ", "))" return [throwType?.description, returnString, whereString].compactMap { $0 }.joined(separator: " ") diff --git a/Generator/Source/CuckooGeneratorFramework/Tokens/WrappableType.swift b/Generator/Source/CuckooGeneratorFramework/Tokens/WrappableType.swift index 38f5ccb..d573ce7 100644 --- a/Generator/Source/CuckooGeneratorFramework/Tokens/WrappableType.swift +++ b/Generator/Source/CuckooGeneratorFramework/Tokens/WrappableType.swift @@ -24,17 +24,6 @@ public enum WrappableType { } } - public var sugarizedExplicitOnly: String { - switch self { - case .optional(let wrapped), .implicitlyUnwrappedOptional(let wrapped): - return "\(wrapped.sugarizedExplicitOnly)?" - case .attributed(let wrapped, let attributes): - return "\(attributes.joined(separator: " ")) \(wrapped.sugarizedExplicitOnly)" - case .type(let type): - return type - } - } - public var desugarized: String { switch self { case .optional(let wrapped), .implicitlyUnwrappedOptional(let wrapped): @@ -46,6 +35,17 @@ public enum WrappableType { } } + public var explicitOptionalOnly: WrappableType { + switch self { + case .optional(let wrapped), .implicitlyUnwrappedOptional(let wrapped): + return .optional(wrapped.explicitOptionalOnly) + case .attributed(let wrapped, let attributes): + return .attributed(wrapped.explicitOptionalOnly, attributes: attributes) + case .type: + return self + } + } + public var unoptionaled: WrappableType { switch self { case .optional(let wrapped), .implicitlyUnwrappedOptional(let wrapped): @@ -76,8 +76,8 @@ public enum WrappableType { return .implicitlyUnwrappedOptional(wrapped.withoutAttributes) case .attributed(let wrapped, _): return wrapped - case .type(let typeString): - return .type(typeString) + case .type: + return self } } diff --git a/Generator/Source/CuckooGeneratorFramework/Utils.swift b/Generator/Source/CuckooGeneratorFramework/Utils.swift index c08c222..043e9d2 100644 --- a/Generator/Source/CuckooGeneratorFramework/Utils.swift +++ b/Generator/Source/CuckooGeneratorFramework/Utils.swift @@ -18,13 +18,6 @@ extension String { return components(separatedBy: occurence).first } - func matches(for regex: String) throws -> [String] { - let regex = try NSRegularExpression(pattern: regex) - let nsString = self as NSString - let results = regex.matches(in: self, range: NSRange(location: 0, length: nsString.length)) - return results.map { nsString.substring(with: $0.range(at: 1)) } - } - subscript(range: Range) -> String { let stringRange = index(startIndex, offsetBy: range.lowerBound).. CountableRange? { - guard let - offset = (dictionary[offset.rawValue] as? Int64).map(Int.init), - let length = (dictionary[length.rawValue] as? Int64).map(Int.init) - else { return nil } + guard let offset = (dictionary[offset.rawValue] as? Int64).map(Int.init), + let length = (dictionary[length.rawValue] as? Int64).map(Int.init) else { return nil } return offset..