Skip to content

Commit

Permalink
#14 #34 Added very basic version of Foundation transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
angelolloqui committed Dec 10, 2017
1 parent b4c24db commit 8b94a81
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 6 deletions.
3 changes: 2 additions & 1 deletion Sources/SwiftKotlinApp/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class ViewController: NSViewController {
let swiftTokenizer = SwiftTokenizer()
let kotlinTokenizer = KotlinTokenizer(
tokenTransformPlugins: [
XCTTestToJUnitTokenTransformPlugin()
XCTTestToJUnitTokenTransformPlugin(),
FoundationMethodsTransformPlugin()
]
)

Expand Down
7 changes: 6 additions & 1 deletion Sources/SwiftKotlinCommandLine/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
import Foundation
import SwiftKotlinFramework

let kotlinTokenizer = KotlinTokenizer()
let kotlinTokenizer = KotlinTokenizer(
tokenTransformPlugins: [
XCTTestToJUnitTokenTransformPlugin(),
FoundationMethodsTransformPlugin()
]
)
let version = "0.1.0"
let arguments = [
"output",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// FoundationMethodsTransformPlugin.swift
// SwiftKotlinPackageDescription
//
// Created by Angel Luis Garcia on 10/12/2017.
//

import Foundation
import Transform
import AST

public class FoundationMethodsTransformPlugin: TokenTransformPlugin {
public var name: String {
return "Foundation transformations"
}

public var description: String {
return "Transforms methods on lists, maps,... like `first`, `count`... to their Kotlin variant"
}

public init() {}

public func transform(tokens: [Token], topDeclaration: TopLevelDeclaration) throws -> [Token] {
var newTokens = [Token]()

for token in tokens {
if token.kind == .identifier,
let memberExpression = token.origin as? ExplicitMemberExpression,
case ExplicitMemberExpression.Kind.namedType(let expression, let identifier) = memberExpression.kind,
let inferredType = inferTypeFor(expression: expression, topDeclaration: topDeclaration),
let replace = memberStringMappings[inferredType]?[identifier] {
newTokens.append(memberExpression.newToken(.identifier, replace))
} else if token.kind == .identifier, token.value == "fatalError", let origin = token.origin, let node = token.node {
newTokens.append(origin.newToken(.keyword, "throw", node))
newTokens.append(origin.newToken(.space, " ", node))
newTokens.append(origin.newToken(.identifier, "Exception", node))
} else {
newTokens.append(token)
}
}

return newTokens
}

func inferTypeFor(expression: PostfixExpression, topDeclaration: TopLevelDeclaration) -> String? {
// TODO: Right now there is no way to infer types. Will be fixed in future versions of AST
return "List"
}

let memberStringMappings = [
"List": [
"first": "firstOrNull()",
"last": "lastOrNull()",
"count": "size",
"isEmpty": "isEmpty()"
],
"String": [
"count": "length",
"uppercased": "toUpperCase",
"lowercased": "toLowerCase"
]
]

// TODO: How to map regex expressions that affect multiple tokens?
let memberRegexMappings = [
"List": [
"index(of: \\(.+))": "indexOf($1)",
"append(\\(.+))": "add($1)",
"remove(at: \\(.+))": "removeAt($1)",
"sorted(by: \\(.+))": "sortedWith(comparator = Comparator($1))",
"joined(separator: \\(.+))": "joinToString(separator = $1)"
]
]
}
4 changes: 4 additions & 0 deletions SwiftKotlin.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
789D79041F927B63009ED628 /* AST+Operations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789D79011F927A66009ED628 /* AST+Operations.swift */; };
78CAB0CF1F92808E009E2608 /* XCTTestToJUnitTokenTransformPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CAB0CE1F92808E009E2608 /* XCTTestToJUnitTokenTransformPlugin.swift */; };
78CAB0D61F92843C009E2608 /* TransformPluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CAB0D51F92843C009E2608 /* TransformPluginTests.swift */; };
78FE79801FDDABC000B64A2C /* FoundationMethodsTransformPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78FE797E1FDDAB5900B64A2C /* FoundationMethodsTransformPlugin.swift */; };
OBJ_265 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; };
OBJ_271 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_39 /* Package.swift */; };
OBJ_277 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_230 /* Package.swift */; };
Expand Down Expand Up @@ -1027,6 +1028,7 @@
78CAB0CE1F92808E009E2608 /* XCTTestToJUnitTokenTransformPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTTestToJUnitTokenTransformPlugin.swift; sourceTree = "<group>"; };
78CAB0D41F9283D6009E2608 /* Tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Tests; sourceTree = "<group>"; };
78CAB0D51F92843C009E2608 /* TransformPluginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransformPluginTests.swift; sourceTree = "<group>"; };
78FE797E1FDDAB5900B64A2C /* FoundationMethodsTransformPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationMethodsTransformPlugin.swift; sourceTree = "<group>"; };
OBJ_100 /* AssignmentOperatorExpression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssignmentOperatorExpression.swift; sourceTree = "<group>"; };
OBJ_101 /* BinaryOperatorExpression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryOperatorExpression.swift; sourceTree = "<group>"; };
OBJ_102 /* ClosureExpression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosureExpression.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1444,6 +1446,7 @@
children = (
789D78F91F92792E009ED628 /* TransformPlugin.swift */,
78CAB0CE1F92808E009E2608 /* XCTTestToJUnitTokenTransformPlugin.swift */,
78FE797E1FDDAB5900B64A2C /* FoundationMethodsTransformPlugin.swift */,
);
path = plugins;
sourceTree = "<group>";
Expand Down Expand Up @@ -2501,6 +2504,7 @@
buildActionMask = 0;
files = (
78314DD61FC8B64700539A2D /* TokenizationResult.swift in Sources */,
78FE79801FDDABC000B64A2C /* FoundationMethodsTransformPlugin.swift in Sources */,
OBJ_358 /* KotlinTokenizer.swift in Sources */,
789D78FB1F927957009ED628 /* TransformPlugin.swift in Sources */,
OBJ_360 /* TransformOptions.swift in Sources */,
Expand Down
7 changes: 6 additions & 1 deletion Tests/SwiftKotlinFrameworkTests/KotlinTokenizerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import XCTest
import SwiftKotlinFramework

class KotlinTokenizerTests: XCTestCase {
let kotlinTokenizer = KotlinTokenizer()
let kotlinTokenizer = KotlinTokenizer(
tokenTransformPlugins: [
XCTTestToJUnitTokenTransformPlugin(),
FoundationMethodsTransformPlugin()
]
)

func testAll() {
let files = try! FileManager().contentsOfDirectory(atPath: self.testFilePath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ val obj = obj as? Movie
if (obj != null) {}
val movie = obj2 as? Movie
if (movie != null) {}
if (numbers.flatMap({ it % 2 }).count == 1) {}
if (numbers.flatMap({ it % 2 }).size == 1) {}
for (current in someObjects) {}
for (i in 0 until count) {}
for (i in 1 .. 3) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ val label = if (x > 0) "Positive" else "negative"
button.color = if (item.deleted) red else green
val text = label ?: "default"
service.deleteObject()
this.service.fetchData()?.user?.name?.count
this.data.filter { it.item?.value == 1 }.map { it.key }.first?.name?.count
this.service.fetchData()?.user?.name?.size
this.data.filter { it.item?.value == 1 }.map { it.key }.firstOrNull()?.name?.size
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
val list = listOf(1, 2, 3)
list.firstOrNull()
list.lastOrNull()
list.size
list.isEmpty()
throw Exception("An error ${error} occurred")
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
let list = [1, 2, 3]

list.first
list.last
list.count
list.isEmpty
//list.index(of: a) --> list.indexOf(a)
//list.append(element) --> list.add(element)
//list.remove(at: index) --> list.removeAt(index)
//list.sorted(by: lambda) --> sortedWith(comparator = Comparator(lambda))
//list.joined(separator: joiner) --> elements. joinToString(separator = joiner)

//let string = "A string"
//string.count --> string.length
//string.uppercased() --> string.toUpperCase()
//string.lowercased() --> string.toLowerCase()

fatalError("An error \(error) occurred")

6 changes: 6 additions & 0 deletions Tests/SwiftKotlinFrameworkTests/TransformPluginTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ class TransformPluginTests: XCTestCase {
file: "XCTTestToJUnitTokenTransformPlugin")
}

func testFoundationTransformPlugin() {
try! testTokenTransformPlugin(
plugin: FoundationMethodsTransformPlugin(),
file: "FoundationMethodsTransformPlugin")
}

}

extension TransformPluginTests {
Expand Down

0 comments on commit 8b94a81

Please sign in to comment.