diff --git a/Assets/Tests/KotlinTokenizer/overrideargs.kt b/Assets/Tests/KotlinTokenizer/overrideargs.kt new file mode 100644 index 0000000..14dd0d6 --- /dev/null +++ b/Assets/Tests/KotlinTokenizer/overrideargs.kt @@ -0,0 +1,7 @@ + +class Test { + + override fun dostuff(x: Int) {} + + fun otherMethod(x: Int = 5) {} +} diff --git a/Assets/Tests/KotlinTokenizer/overrideargs.swift b/Assets/Tests/KotlinTokenizer/overrideargs.swift new file mode 100644 index 0000000..d5cce7b --- /dev/null +++ b/Assets/Tests/KotlinTokenizer/overrideargs.swift @@ -0,0 +1,8 @@ +class Test { + override func dostuff(x: Int = 5) { + } + + func otherMethod(x: Int = 5) { + } +} + diff --git a/Sources/SwiftKotlinFramework/KotlinTokenizer.swift b/Sources/SwiftKotlinFramework/KotlinTokenizer.swift index fde5b74..1712163 100644 --- a/Sources/SwiftKotlinFramework/KotlinTokenizer.swift +++ b/Sources/SwiftKotlinFramework/KotlinTokenizer.swift @@ -21,7 +21,7 @@ public class KotlinTokenizer: SwiftTokenizer { .replacing({ $0.value == "let"}, with: [constant.newToken(.keyword, "val")]) } - + open override func tokenize(_ declaration: FunctionDeclaration) -> [Token] { let attrsTokens = tokenize(declaration.attributes, node: declaration) let modifierTokens = declaration.modifiers.map { tokenize($0, node: declaration) } @@ -35,15 +35,21 @@ public class KotlinTokenizer: SwiftTokenizer { genericParameterClauseTokens ].joined(token: declaration.newToken(.space, " ")) - let signatureTokens = tokenize(declaration.signature, node: declaration) + var signatureTokens = tokenize(declaration.signature, node: declaration) let bodyTokens = declaration.body.map(tokenize) ?? [] - - return [ + + if declaration.isOverride { + // overridden methods can't have default args in kotlin: + signatureTokens = removeDefaultArgsFromParameters(tokens:signatureTokens) + } + let tokens = [ headTokens, [declaration.newToken(.identifier, declaration.name)] + signatureTokens, bodyTokens ].joined(token: declaration.newToken(.space, " ")) .prefix(with: declaration.newToken(.linebreak, "\n")) + + return tokens } open override func tokenize(_ parameter: FunctionSignature.Parameter, node: ASTNode) -> [Token] { @@ -1071,10 +1077,39 @@ public class KotlinTokenizer: SwiftTokenizer { interpolatedString += remainingText return [node.newToken(.string, interpolatedString)] } + + // function used to remove default arguments from override functions, since kotlin doesn't have them + private func removeDefaultArgsFromParameters(tokens:[Token]) -> [Token] { + var newTokens = [Token]() + var removing = false + var bracket = false + for t in tokens { + if removing && t.kind == .startOfScope && t.value == "(" { + bracket = true + } + if bracket && t.kind == .endOfScope && t.value == ")" { + bracket = false + removing = false + continue + } + if t.kind == .symbol && (t.value.contains("=")) { + removing = true + } + if t.kind == .delimiter && t.value.contains(",") { + removing = false + } + if !bracket && removing && t.kind == .endOfScope && t.value == ")" { + removing = false + } + if !removing { + newTokens.append(t) + } + } + return newTokens + } } public typealias InvertedConditionList = [InvertedCondition] public struct InvertedCondition: ASTTokenizable { public let condition: Condition } - diff --git a/Sources/SwiftKotlinFramework/utils/AST+Operations.swift b/Sources/SwiftKotlinFramework/utils/AST+Operations.swift index 7e098c3..c0fb1fd 100644 --- a/Sources/SwiftKotlinFramework/utils/AST+Operations.swift +++ b/Sources/SwiftKotlinFramework/utils/AST+Operations.swift @@ -54,6 +54,9 @@ extension FunctionDeclaration { var isStatic: Bool { return modifiers.isStatic } + var isOverride: Bool { + return modifiers.isOverride + } } extension StructDeclaration.Member { @@ -118,6 +121,10 @@ extension Collection where Iterator.Element == DeclarationModifier { var isLazy: Bool { return self.contains(where: { $0.isLazy }) } + + var isOverride: Bool { + return self.contains(where: { $0.isOverride }) + } } extension DeclarationModifier { @@ -134,6 +141,13 @@ extension DeclarationModifier { default: return false } } + + var isOverride: Bool { + switch self { + case .override: return true + default: return false + } + } } extension SuperclassExpression {