Improve code stylistically.

This commit is contained in:
Matyáš Kříž 2019-11-06 13:45:16 +01:00
parent 674ecd9de6
commit ed1e947e1f
5 changed files with 44 additions and 63 deletions

View File

@ -112,6 +112,7 @@ public struct Generator {
if parameter.isClosure && !parameter.isEscaping { if parameter.isClosure && !parameter.isEscaping {
let indents = String(repeating: "\t", count: index) let indents = String(repeating: "\t", count: index)
let tries = method.isThrowing ? "try " : "" let tries = method.isThrowing ? "try " : ""
let sugarizedReturnType = method.returnType.sugarized let sugarizedReturnType = method.returnType.sugarized
let returnSignature: String let returnSignature: String
if sugarizedReturnType.isEmpty { 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" fullString += "\(indents)return \(tries)withoutActuallyEscaping(\(parameter.name), do: { (\(parameter.name): @escaping \(parameter.type))\(returnSignature) in\n"
} }
} }
return fullString return fullString
} }

View File

@ -6,6 +6,8 @@
// Copyright © 2016 Brightify. All rights reserved. // Copyright © 2016 Brightify. All rights reserved.
// //
import Foundation
public protocol Method: Token, HasAccessibility { public protocol Method: Token, HasAccessibility {
var name: String { get } var name: String { get }
var returnSignature: ReturnSignature { get } var returnSignature: ReturnSignature { get }
@ -79,37 +81,23 @@ public extension Method {
}.joined(separator: ", ") }.joined(separator: ", ")
let stubFunctionPrefix = isOverriding ? "Class" : "Protocol" let stubFunctionPrefix = isOverriding ? "Class" : "Protocol"
let stubFunction: String let returnString = returnType.sugarized == "Void" ? "NoReturn" : ""
if isThrowing { let throwingString = isThrowing ? "Throwing" : ""
if returnType.sugarized == "Void" { let stubFunction = "Cuckoo.\(stubFunctionPrefix)Stub\(returnString)\(throwingString)Function"
stubFunction = "Cuckoo.\(stubFunctionPrefix)StubNoReturnThrowingFunction"
} else {
stubFunction = "Cuckoo.\(stubFunctionPrefix)StubThrowingFunction"
}
} else {
if returnType.sugarized == "Void" {
stubFunction = "Cuckoo.\(stubFunctionPrefix)StubNoReturnFunction"
} else {
stubFunction = "Cuckoo.\(stubFunctionPrefix)StubFunction"
}
}
let escapingParameterNames = parameters.map { parameter in let escapingParameterNames = parameters.map { parameter in
if parameter.isClosure && !parameter.isEscaping { if parameter.isClosure && !parameter.isEscaping {
let parameterCount = parameter.closureParamCount let parameterCount = parameter.closureParamCount
let parameterSignature = parameterCount > 0 ? (1...parameterCount).map { _ in "_" }.joined(separator: ", ") : "()" let parameterSignature = parameterCount > 0 ? (1...parameterCount).map { _ in "_" }.joined(separator: ", ") : "()"
var returnSignature = ""
if !parameter.type.sugarized.isEmpty { // FIXME: Instead of parsing the closure return type here, Tokenizer should do it and pass the information in a data structure
returnSignature = extractClosureReturnType(parameter: parameter.type.sugarized) ?? "" let returnSignature: String
if !returnSignature.isEmpty { let closureReturnType = extractClosureReturnType(parameter: parameter.type.sugarized)
if returnSignature != "Void" { if let closureReturnType = closureReturnType, !closureReturnType.isEmpty && closureReturnType != "Void" {
returnSignature = " -> " + returnSignature returnSignature = " -> " + closureReturnType
} else { } else {
returnSignature = "" returnSignature = ""
} }
}
}
return "{ \(parameterSignature)\(returnSignature) in fatalError(\"This is a stub! It's not supposed to be called!\") }" return "{ \(parameterSignature)\(returnSignature) in fatalError(\"This is a stub! It's not supposed to be called!\") }"
} else { } else {
return parameter.name return parameter.name
@ -128,7 +116,7 @@ public extension Method {
"parameterNames": parameters.map { $0.name }.joined(separator: ", "), "parameterNames": parameters.map { $0.name }.joined(separator: ", "),
"escapingParameterNames": escapingParameterNames, "escapingParameterNames": escapingParameterNames,
"isInit": isInit, "isInit": isInit,
"returnType": returnType.sugarizedExplicitOnly, "returnType": returnType.explicitOptionalOnly.sugarized,
"isThrowing": isThrowing, "isThrowing": isThrowing,
"throwType": returnSignature.throwType?.description ?? "", "throwType": returnSignature.throwType?.description ?? "",
"fullyQualifiedName": fullyQualifiedName, "fullyQualifiedName": fullyQualifiedName,
@ -146,25 +134,25 @@ public extension Method {
"genericParameters": isGeneric ? "<\(genericParametersString)>" : "", "genericParameters": isGeneric ? "<\(genericParametersString)>" : "",
] ]
} }
private func extractClosureReturnType(parameter: String) -> String? { private func extractClosureReturnType(parameter: String) -> String? {
var parentLevel = 0 var parenLevel = 0
for i in 0..<parameter.count { for i in 0..<parameter.count {
let index = parameter.index(parameter.startIndex, offsetBy: i) let index = parameter.index(parameter.startIndex, offsetBy: i)
if parameter[index] == "(" { let character = parameter[index]
parentLevel += 1 if character == "(" {
} parenLevel += 1
else if (parameter[index] == ")") { } else if character == ")" {
parentLevel -= 1 parenLevel -= 1
if parentLevel == 0 { if parenLevel == 0 {
let afterClosure = String(parameter[parameter.index(after: index)..<parameter.endIndex]) let returnSignature = String(parameter[parameter.index(after: index)..<parameter.endIndex])
do { let regex = try! NSRegularExpression(pattern: "\\s*->\\s*(.*)\\s*")
return try afterClosure.matches(for: "\\s*->\\s*(.*)\\s*").first guard let result = regex.matches(in: returnSignature, range: NSRange(location: 0, length: returnSignature.count)).first else { return nil }
} catch let error { return returnSignature[result.range(at: 1)]
fatalError("Invalid regex:" + error.localizedDescription)
}
} }
} }
} }
return nil return nil
} }
} }

View File

@ -25,7 +25,7 @@ public struct ReturnSignature {
extension ReturnSignature: CustomStringConvertible { extension ReturnSignature: CustomStringConvertible {
public var description: String { public var description: String {
let trimmedReturnType = returnType.sugarizedExplicitOnly.trimmed let trimmedReturnType = returnType.explicitOptionalOnly.sugarized.trimmed
let returnString = trimmedReturnType.isEmpty || trimmedReturnType == "Void" ? nil : "-> \(returnType)" let returnString = trimmedReturnType.isEmpty || trimmedReturnType == "Void" ? nil : "-> \(returnType)"
let whereString = whereConstraints.isEmpty ? nil : "where \(whereConstraints.joined(separator: ", "))" let whereString = whereConstraints.isEmpty ? nil : "where \(whereConstraints.joined(separator: ", "))"
return [throwType?.description, returnString, whereString].compactMap { $0 }.joined(separator: " ") return [throwType?.description, returnString, whereString].compactMap { $0 }.joined(separator: " ")

View File

@ -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 { public var desugarized: String {
switch self { switch self {
case .optional(let wrapped), .implicitlyUnwrappedOptional(let wrapped): 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 { public var unoptionaled: WrappableType {
switch self { switch self {
case .optional(let wrapped), .implicitlyUnwrappedOptional(let wrapped): case .optional(let wrapped), .implicitlyUnwrappedOptional(let wrapped):
@ -76,8 +76,8 @@ public enum WrappableType {
return .implicitlyUnwrappedOptional(wrapped.withoutAttributes) return .implicitlyUnwrappedOptional(wrapped.withoutAttributes)
case .attributed(let wrapped, _): case .attributed(let wrapped, _):
return wrapped return wrapped
case .type(let typeString): case .type:
return .type(typeString) return self
} }
} }

View File

@ -18,13 +18,6 @@ extension String {
return components(separatedBy: occurence).first 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<Int>) -> String { subscript(range: Range<Int>) -> String {
let stringRange = index(startIndex, offsetBy: range.lowerBound)..<index(startIndex, offsetBy: range.upperBound) let stringRange = index(startIndex, offsetBy: range.lowerBound)..<index(startIndex, offsetBy: range.upperBound)
return String(self[stringRange]) return String(self[stringRange])
@ -64,10 +57,8 @@ extension Sequence {
} }
internal func extractRange(from dictionary: [String: SourceKitRepresentable], offset: Key, length: Key) -> CountableRange<Int>? { internal func extractRange(from dictionary: [String: SourceKitRepresentable], offset: Key, length: Key) -> CountableRange<Int>? {
guard let guard let offset = (dictionary[offset.rawValue] as? Int64).map(Int.init),
offset = (dictionary[offset.rawValue] as? Int64).map(Int.init), let length = (dictionary[length.rawValue] as? Int64).map(Int.init) else { return nil }
let length = (dictionary[length.rawValue] as? Int64).map(Int.init)
else { return nil }
return offset..<offset.advanced(by: length) return offset..<offset.advanced(by: length)
} }