diff --git a/Sources/MockoloFramework/Parsers/ViaSwiftSyntax/ParserViaSwiftSyntax.swift b/Sources/MockoloFramework/Parsers/ViaSwiftSyntax/ParserViaSwiftSyntax.swift index bb70b476..79be1407 100644 --- a/Sources/MockoloFramework/Parsers/ViaSwiftSyntax/ParserViaSwiftSyntax.swift +++ b/Sources/MockoloFramework/Parsers/ViaSwiftSyntax/ParserViaSwiftSyntax.swift @@ -70,7 +70,11 @@ public class ParserViaSwiftSyntax: SourceParsing { var results = [Entity]() let node = try SyntaxParser.parse(path) var treeVisitor = EntityVisitor(path, annotation: annotation, declType: declType) + #if swift(>=5.2) + treeVisitor.walk(node) + #else node.walk(&treeVisitor) + #endif let ret = treeVisitor.entities results.append(contentsOf: ret) let imports = treeVisitor.imports diff --git a/Sources/MockoloFramework/Parsers/ViaSwiftSyntax/SwiftSyntaxExtensions.swift b/Sources/MockoloFramework/Parsers/ViaSwiftSyntax/SwiftSyntaxExtensions.swift index ce9fde66..8ee8758d 100644 --- a/Sources/MockoloFramework/Parsers/ViaSwiftSyntax/SwiftSyntaxExtensions.swift +++ b/Sources/MockoloFramework/Parsers/ViaSwiftSyntax/SwiftSyntaxExtensions.swift @@ -27,7 +27,8 @@ extension SyntaxParser { } } -extension Syntax { +#if swift(>=5.2) +extension SyntaxProtocol { var offset: Int64 { return Int64(self.position.utf8Offset) } @@ -36,6 +37,17 @@ extension Syntax { return Int64(self.totalLength.utf8Length) } } +#else +extension Syntax { + var offset: Int64 { + return Int64(self.position.utf8Offset) + } + + var length: Int64 { + return Int64(self.totalLength.utf8Length) + } +} +#endif extension AttributeListSyntax { var trimmedDescription: String? { @@ -146,40 +158,40 @@ extension MemberDeclListItemSyntax { } func transformToModel(with encloserAcl: String, declType: DeclType, metadata: AnnotationMetadata?, processed: Bool) -> (Model, String?, Bool)? { - if let varMember = self.decl as? VariableDeclSyntax { + if let varMember = self.decl.as(VariableDeclSyntax.self) { if validateMember(varMember.modifiers, declType, processed: processed) { let acl = memberAcl(varMember.modifiers, encloserAcl, declType) if let item = varMember.models(with: acl, declType: declType, overrides: metadata?.varTypes, processed: processed).first { return (item, varMember.attributes?.trimmedDescription, false) } } - } else if let funcMember = self.decl as? FunctionDeclSyntax { + } else if let funcMember = self.decl.as(FunctionDeclSyntax.self) { if validateMember(funcMember.modifiers, declType, processed: processed) { let acl = memberAcl(funcMember.modifiers, encloserAcl, declType) let item = funcMember.model(with: acl, declType: declType, processed: processed) return (item, funcMember.attributes?.trimmedDescription, false) } - } else if let subscriptMember = self.decl as? SubscriptDeclSyntax { + } else if let subscriptMember = self.decl.as(SubscriptDeclSyntax.self) { if validateMember(subscriptMember.modifiers, declType, processed: processed) { let acl = memberAcl(subscriptMember.modifiers, encloserAcl, declType) let item = subscriptMember.model(with: acl, declType: declType, processed: processed) return (item, subscriptMember.attributes?.trimmedDescription, false) } - } else if let initMember = self.decl as? InitializerDeclSyntax { + } else if let initMember = self.decl.as(InitializerDeclSyntax.self) { if validateInit(initMember, declType, processed: processed) { let acl = memberAcl(initMember.modifiers, encloserAcl, declType) let item = initMember.model(with: acl, declType: declType, processed: processed) return (item, initMember.attributes?.trimmedDescription, true) } - } else if let patMember = self.decl as? AssociatedtypeDeclSyntax { + } else if let patMember = self.decl.as(AssociatedtypeDeclSyntax.self) { let acl = memberAcl(patMember.modifiers, encloserAcl, declType) let item = patMember.model(with: acl, declType: declType, overrides: metadata?.typeAliases, processed: processed) return (item, patMember.attributes?.trimmedDescription, false) - } else if let taMember = self.decl as? TypealiasDeclSyntax { + } else if let taMember = self.decl.as(TypealiasDeclSyntax.self) { let acl = memberAcl(taMember.modifiers, encloserAcl, declType) let item = taMember.model(with: acl, declType: declType, overrides: metadata?.typeAliases, processed: processed) return (item, taMember.attributes?.trimmedDescription, false) - } else if let ifMacroMember = self.decl as? IfConfigDeclSyntax { + } else if let ifMacroMember = self.decl.as(IfConfigDeclSyntax.self) { let (item, attr, initFlag) = ifMacroMember.model(with: encloserAcl, declType: declType, metadata: metadata, processed: processed) return (item, attr, initFlag) } @@ -191,7 +203,7 @@ extension MemberDeclListItemSyntax { extension MemberDeclListSyntax { var hasBlankInit: Bool { for member in self { - if let varMember = member.decl as? VariableDeclSyntax { + if let varMember = member.decl.as(VariableDeclSyntax.self) { for v in varMember.bindings { if let name = v.pattern.firstToken?.text { if name == String.hasBlankInit { @@ -230,7 +242,7 @@ extension IfConfigDeclSyntax { var name = "" for cl in self.clauses { - if let desc = cl.condition?.description, let list = cl.elements as? MemberDeclListSyntax { + if let desc = cl.condition?.description, let list = cl.elements.as(MemberDeclListSyntax.self) { name = desc for element in list { @@ -575,8 +587,14 @@ final class EntityVisitor: SyntaxVisitor { entities = [] imports = [] } - - func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind { + + #if swift(>=5.2) + override func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind { visitImpl(node) } + #else + func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind { visitImpl(node) } + #endif + + private func visitImpl(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind { let metadata = node.annotationMetadata(with: annotation) if let ent = Entity.node(with: node, filepath: path, isPrivate: node.isPrivate, isFinal: false, metadata: metadata, processed: false) { entities.append(ent) @@ -584,7 +602,13 @@ final class EntityVisitor: SyntaxVisitor { return .skipChildren } - func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind { + #if swift(>=5.2) + override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind { visitImpl(node) } + #else + func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind { visitImpl(node) } + #endif + + private func visitImpl(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind { if node.name.hasSuffix("Mock") { // this mock class node must be public else wouldn't have compiled before if let ent = Entity.node(with: node, filepath: path, isPrivate: node.isPrivate, isFinal: false, metadata: nil, processed: true) { @@ -600,8 +624,14 @@ final class EntityVisitor: SyntaxVisitor { } return .skipChildren } - - func visit(_ node: ImportDeclSyntax) -> SyntaxVisitorContinueKind { + + #if swift(>=5.2) + override func visit(_ node: ImportDeclSyntax) -> SyntaxVisitorContinueKind { visitImpl(node) } + #else + func visit(_ node: ImportDeclSyntax) -> SyntaxVisitorContinueKind { visitImpl(node) } + #endif + + private func visitImpl(_ node: ImportDeclSyntax) -> SyntaxVisitorContinueKind { if let ret = node.path.firstToken?.text { let desc = node.importTok.text + " " + ret imports.append(desc) @@ -686,4 +716,13 @@ extension Trivia { } } - +#if swift(<5.2) +private extension Syntax { + /// A shim function for source compatibility between SwiftSyntax + /// 0.50100.0 and 0.50200.0. + /// - See Also: https://github.com/apple/swift-syntax/blob/master/Changelog.md#swift-52 + func `as`(_ syntaxType: S.Type) -> S? { + return self as? S + } +} +#endif