Skip to content

Avoid Special Handling of the "Unknown" Type Name #299

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions Sources/MockoloFramework/Models/MethodModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public enum MethodKind: Equatable {

final class MethodModel: Model {
let name: String
let returnType: SwiftType
let returnType: SwiftType?
let accessLevel: String
let kind: MethodKind
let offset: Int64
Expand Down Expand Up @@ -114,10 +114,11 @@ final class MethodModel: Model {
args.append(genericWhereClauseToSignatureComponent)
}
args.append(contentsOf: paramTypes.map(\.displayName))
var displayType = self.returnType.displayName
let capped = min(displayType.count, 32)
displayType.removeLast(displayType.count-capped)
args.append(displayType)
if var displayType = self.returnType?.displayName {
let capped = min(displayType.count, 32)
displayType.removeLast(displayType.count-capped)
args.append(displayType)
}
args.append(self.staticKind)
let ret = args.filter{ arg in !arg.isEmpty }
return ret
Expand Down Expand Up @@ -145,11 +146,11 @@ final class MethodModel: Model {
params: params.map { ($0.name, $0.type) },
isAsync: isAsync,
throwing: throwing,
returnType: returnType)
returnType: returnType ?? .init(.voidType))
}

init(name: String,
typeName: String,
typeName: String?,
kind: MethodKind,
acl: String,
genericTypeParams: [ParamModel],
Expand All @@ -165,7 +166,7 @@ final class MethodModel: Model {
modelDescription: String?,
processed: Bool) {
self.name = name.trimmingCharacters(in: .whitespaces)
self.returnType = SwiftType(typeName.trimmingCharacters(in: .whitespaces))
self.returnType = typeName.map { SwiftType($0.trimmingCharacters(in: .whitespaces)) }
self.isAsync = isAsync
self.throwing = throwing
self.offset = offset
Expand Down
2 changes: 1 addition & 1 deletion Sources/MockoloFramework/Models/ParamModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ final class ParamModel: Model {
context: RenderContext,
arguments: GenerationArguments
) -> String? {
return applyParamTemplate(name: name, label: label, type: type, inInit: inInit)
return applyParamTemplate(name: name, label: label, type: type, inInit: inInit, isGeneric: isGeneric)
}
}

Expand Down
12 changes: 8 additions & 4 deletions Sources/MockoloFramework/Models/VariableModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class VariableModel: Model {
}

let name: String
let type: SwiftType
let type: SwiftType?
let offset: Int64
let accessLevel: String
let attributes: [String]?
Expand All @@ -39,14 +39,14 @@ final class VariableModel: Model {
}

var underlyingName: String {
if type.defaultVal() == nil {
if type?.defaultVal() == nil {
return "_\(name)"
}
return name
}

init(name: String,
type: SwiftType,
type: SwiftType?,
acl: String?,
isStatic: Bool,
storageKind: MockStorageKind,
Expand Down Expand Up @@ -89,13 +89,17 @@ final class VariableModel: Model {
if let propertyWrapper = propertyWrapper, !modelDescription.contains(propertyWrapper) {
prefix = "\(propertyWrapper) "
}
if shouldOverride, !name.isGenerated(type: type) {
if let type, shouldOverride, !name.isGenerated(type: type) {
prefix += "\(String.override) "
}

return prefix + modelDescription
}

guard let type else {
return nil
}

if !arguments.disableCombineDefaultValues {
if let combineVar = applyCombineVariableTemplate(name: name,
type: type,
Expand Down
12 changes: 6 additions & 6 deletions Sources/MockoloFramework/Parsers/SwiftSyntaxExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,8 @@ extension VariableDeclSyntax {

// Need to access pattern bindings to get name, type, and other info of a var decl
let varmodels = self.bindings.compactMap { (v: PatternBindingSyntax) -> Model in
let name = v.pattern.firstToken(viewMode: .sourceAccurate)?.text ?? String.unknownVal
var typeName = ""
let name = v.pattern.trimmedDescription
var typeName: String?
var potentialInitParam = false

// Get the type info and whether it can be a var param for an initializer
Expand Down Expand Up @@ -473,7 +473,7 @@ extension VariableDeclSyntax {
}

return VariableModel(name: name,
type: SwiftType(typeName),
type: typeName.map { SwiftType($0) },
acl: acl,
isStatic: isStatic,
storageKind: storageKind,
Expand Down Expand Up @@ -531,7 +531,7 @@ extension FunctionDeclSyntax {
let genericWhereClause = self.genericWhereClause?.description

let funcmodel = MethodModel(name: self.name.description,
typeName: self.signature.returnClause?.type.description ?? "",
typeName: self.signature.returnClause?.type.description,
kind: .funcKind,
acl: acl,
genericTypeParams: genericTypeParams,
Expand Down Expand Up @@ -575,7 +575,7 @@ extension InitializerDeclSyntax {
let genericWhereClause = self.genericWhereClause?.description

return MethodModel(name: "init",
typeName: "",
typeName: nil,
kind: .initKind(required: requiredInit, override: declKind == .class),
acl: acl,
genericTypeParams: genericTypeParams,
Expand All @@ -599,7 +599,7 @@ extension GenericParameterSyntax {
func model(inInit: Bool) -> ParamModel {
return ParamModel(label: "",
name: self.name.text,
type: SwiftType(self.inheritedType?.trimmedDescription ?? ""),
type: SwiftType(self.inheritedType?.trimmedDescription ?? .voidType),
isGeneric: true,
inInit: inInit,
needsVarDecl: false,
Expand Down
2 changes: 1 addition & 1 deletion Sources/MockoloFramework/Templates/ClosureTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ extension ClosureModel {


private func renderReturnDefaultStatement(name: String, type: SwiftType) -> String {
guard !type.isUnknown else { return "" }
guard !type.isVoid else { return "" }

if let result = type.defaultVal() {
if result.isEmpty {
Expand Down
11 changes: 7 additions & 4 deletions Sources/MockoloFramework/Templates/MethodTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ extension MethodModel {
return arg.name.safeName
}.joined(separator: ", ")

let defaultVal = model.returnType.defaultVal() // ?? "nil"
let defaultVal = model.returnType?.defaultVal()

var mockReturn = ".error"
if model.returnType.typeName.isEmpty {
if model.returnType?.isVoid ?? true {
mockReturn = ".void"
} else if let val = defaultVal {
mockReturn = ".val(\(val))"
Expand Down Expand Up @@ -157,8 +157,11 @@ extension MethodModel {
}

var returnClause: String {
let returnTypeName = model.returnType.isUnknown ? "" : model.returnType.typeName
return returnTypeName.isEmpty ? "" : "-> \(returnTypeName) "
if let returnType = model.returnType {
return "-> \(returnType.typeName) "
} else {
return ""
}
}

var handlerVarName: String {
Expand Down
20 changes: 12 additions & 8 deletions Sources/MockoloFramework/Templates/NominalTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,21 @@ extension NominalModel {
if needParamedInit {
var paramsAssign = ""
let params = initParamCandidates
.map { (element: VariableModel) -> String in
if let val = element.type.defaultVal(with: element.rxTypes, overrideKey: element.name, isInitParam: true) {
return "\(element.name): \(element.type.typeName) = \(val)"
.compactMap { (element: VariableModel) -> String? in
if let val = element.type?.defaultVal(with: element.rxTypes, overrideKey: element.name, isInitParam: true) {
return "\(element.name): \(element.type!.typeName) = \(val)"
}
var prefix = ""
if element.type.hasClosure {
if !element.type.isOptional {
prefix = String.escaping + " "
if let elementType = element.type {
var prefix = ""
if elementType.hasClosure == true {
if !elementType.isOptional {
prefix = String.escaping + " "
}
}
return "\(element.name): \(prefix)\(elementType.typeName)"
} else {
return nil
}
return "\(element.name): \(prefix)\(element.type.typeName)"
}
.joined(separator: ", ")

Expand Down
13 changes: 9 additions & 4 deletions Sources/MockoloFramework/Templates/ParamTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,28 @@ extension ParamModel {
func applyParamTemplate(name: String,
label: String,
type: SwiftType,
inInit: Bool) -> String {
inInit: Bool,
isGeneric: Bool) -> String {
var result = name
if !label.isEmpty {
result = "\(label) \(name)"
}
if !type.isUnknown {
if isGeneric {
// FIXME: `type` is used as a generic constraint
if !type.isVoid {
result = "\(result): \(type.typeName)"
}
} else {
result = "\(result): \(type.typeName)"
}

if inInit, let defaultVal = type.defaultVal() {
result = "\(result) = \(defaultVal)"
}
return result
}

func applyVarTemplate(type: SwiftType) -> String {
assert(!type.isUnknown)
let vardecl = "\(1.tab)private var \(underlyingName): \(type.underlyingType)"
return vardecl
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/MockoloFramework/Templates/VariableTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,14 @@ extension VariableModel {

var template = "\n"
var isWrapperPropertyOptionalOrForceUnwrapped = false
if let publishedAliasModel = wrapperAliasModel {
if let publishedAliasModel = wrapperAliasModel, let type = publishedAliasModel.type {
// If the property required by the protocol/class cannot be optional, the wrapper property will be the underlyingProperty
// i.e. @Published var _myType: MyType!
let wrapperPropertyDefaultValue = publishedAliasModel.type.defaultVal()
let wrapperPropertyDefaultValue = type.defaultVal()
if wrapperPropertyDefaultValue == nil {
wrapperPropertyName = "_\(wrapperPropertyName)"
}
isWrapperPropertyOptionalOrForceUnwrapped = wrapperPropertyDefaultValue == nil || publishedAliasModel.type.isOptional
isWrapperPropertyOptionalOrForceUnwrapped = wrapperPropertyDefaultValue == nil || type.isOptional
}

var mapping = ""
Expand Down
4 changes: 2 additions & 2 deletions Sources/MockoloFramework/Utils/StringExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ extension String {
static let override = "override"
static let privateSet = "private(set)"
static let mockType = "protocol"
static let unknownVal = "Unknown"
static let prefix = "prefix"
static let anyType = "Any"
static let voidType = "()"
static let neverType = "Never"
static let any = "any"
static let some = "some"
Expand Down Expand Up @@ -170,7 +170,7 @@ extension String {


func canBeInitParam(type: String, isStatic: Bool) -> Bool {
return !(isStatic || type == .unknownVal || type.hasPrefix(.anyPublisher) || (type.hasSuffix("?") && type.contains(String.closureArrow)) || isGenerated(type: SwiftType(type)))
return !(isStatic || type.hasPrefix(.anyPublisher) || (type.hasSuffix("?") && type.contains(String.closureArrow)) || isGenerated(type: SwiftType(type)))
}

func isGenerated(type: SwiftType) -> Bool {
Expand Down
19 changes: 9 additions & 10 deletions Sources/MockoloFramework/Utils/TypeParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public final class SwiftType {
var cachedDefaultVal: String?

init(_ type: String){
self.typeName = type == .unknownVal ? "" : type
assert(!type.isEmpty)
self.typeName = type
}

var isInOut: Bool {
Expand All @@ -47,10 +48,6 @@ public final class SwiftType {
return typeName.hasPrefix(.rxObservableLeftAngleBracket) || typeName.hasPrefix(.observableLeftAngleBracket)
}

var isUnknown: Bool {
return typeName.isEmpty || typeName == String.unknownVal
}

var isOptional: Bool {
if !typeName.hasSuffix("?") {
return false
Expand Down Expand Up @@ -172,11 +169,11 @@ public final class SwiftType {
}

var displayName: String {
return typeName.displayableComponents.map{$0 == .unknownVal ? "" : $0.capitalizeFirstLetter}.joined()
return typeName.displayableComponents.map(\.capitalizeFirstLetter).joined()
}

var isIdentifier: Bool {
if isUnknown {
if isVoid {
return false
}

Expand All @@ -199,7 +196,7 @@ public final class SwiftType {
}

var isVoid: Bool {
return typeName.isEmpty || typeName == "()" || typeName == "Void"
return typeName == "()" || typeName == "Void"
}

var hasValidBrackets: Bool {
Expand Down Expand Up @@ -526,8 +523,10 @@ public final class SwiftType {
returnTypeCast = " as! " + String.`Self`
}

if !(SwiftType(displayableReturnType).isSingular || SwiftType(displayableReturnType).isOptional) {
displayableReturnType = "(\(displayableReturnType))"
if !SwiftType(displayableReturnType).isVoid {
if !(SwiftType(displayableReturnType).isSingular || SwiftType(displayableReturnType).isOptional) {
displayableReturnType = "(\(displayableReturnType))"
}
}

let suffixStr = applyFunctionSuffixTemplate(
Expand Down