目前已经实现的效果
昨天让同事随意写了一段JavaSCript代码:
function showdata() {
var array = [0, 1, 2, 3, 4];
var result = true;
if (result) {
for (let index = 0; index < array.length; index++) {
console.log(array[index]);
}
} else {
console.log("noooooo!")
}
var obj = {
name: 'wuli',
sex: 0,
age: 21
};
var string = "woxinshensihai";
if (result) {
console.log(string)
}
console.log(obj);
}
然后用翻译程序进行翻译,结果如下:
func showdata() {
var array = [
0,
1,
2,
3,
4,
]
var result: Bool = true
if result {
for (index, item) in array.enumerated() {
print(array[index])
}
} else {
print("noooooo!")
}
var obj = NamesexageModel(name: "wuli", sex: 0, age: 21)
var string: String = "woxinshensihai"
if result {
print(string)
}
print(obj)
}
生成的Model文件:
class NamesexageModel: NSObject {
var name: String
var sex: Int
var age: Int
}
从效果来看感觉还可以。。。
For 循环翻译
上篇文章中没有涉及 for 循环的翻译,这里补充一下:
JavaScript的For写法和Swift中的差异比较大,主要是因为Javascript 中的 Array 并不像大部分其他语言的数组。首先, Javascript 中的 Array 在内存上并不连续,其次, Array 的索引并不是指偏移量。实际上,Array 的索引也不是 Number 类型,而是 String 类型的。我们可以正确使用如 array[0] 的写法的原因是语言可以自动将 Number 类型的0转换成 String 类型的 “0”
C 风格的 for 循环
这种写法应该是JavaScript中用的最多的
for (let index = 0; index < array.length; index++) {
console.log(array[index]);
}
但是Swift自从Swift3.0开始不再支持C-Type的写法,这就有点蛋疼了
在Swift中的for循环写法
for (index, item) in array.enumerated() {
print(array[index])
}
对比两种语言for循环的实现,for循环方法体内部差不多,但是for循环的写法相差很多,所以我们主要修改 let index = 0; index < array.length; index++ 这一段代码
先看一下for循环的AST:
"body": [
{
"type": "ForStatement",
"init": {
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "index"
},
"init": {
"type": "Literal",
"value": 0,
"raw": "0"
}
}
],
"kind": "let"
},
"test": {
"type": "BinaryExpression",
"left": {
"type": "Identifier",
"name": "index"
},
"operator": "<",
"right": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "array"
},
"property": {
"type": "Identifier",
"name": "length"
},
"computed": false
}
},
"update": {
"type": "UpdateExpression",
"operator": "++",
"prefix": false,
"argument": {
"type": "Identifier",
"name": "index"
}
}
...
...
body 下面的节点是 ForStatement 说明执行的是 escodegen.js 中的 ForStatement 方法,想要从 for (let index = 0; index < array.length; index++) { 转换成 for (index, item) in array.enumerated() { 我们只需要获取到 index关键字、array关键字即可
if (stmt.test) {
// 获取 index 关键字
result.push(stmt.test.left.name)
result.push(', item) in ')
// 获取 array 关键字
result.push(stmt.test.right.object.name)
result.push('.enumerated()')
}
这样就可以生成 for (index, item) in array.enumerated()
这一段代码用来生成 index ++)只需要将它注释掉或者删除即可
if (stmt.update) {
result.push(space);
result.push(that.generateExpression(stmt.update, Precedence.Sequence, E_TTT));
result.push(')');
} else {
result.push(')');
}
ForIn for 循环
for (index in array) {
console.log(array[index]);
}
ForOf for 循环
for (let item of array) {
console.log(item);
}
Swift中对应的写法:
for item in array {
print(item)
}
这里翻译比较简单 只需要将 of 改成 in 即可
代码格式化
翻译程序生成的代码在格式方面不是很美观,这里借助 swiftformat 来对代码进行格式化,swiftformat 的安装很简单,只需要:
> brew update
> brew install swiftformat
通过 JavaScript 执行 swiftformat fileName.swift --swiftversion 4.2
const { exec } = require('child_process');
exec('swiftformat ./Swift_Code/' + fileName + '.swift --swiftversion 4.2 ', (err, stdout, stderr) => {
if(err) {
return;
}
})
关于如何翻译 JavaScript 的网络请求,由于 JavaScript 、Swift 都有各自的网络请求库,这里需要统一方法名、参数,每个语言也需要封装各自的网络请求库;其次,Swift 的JSON解析需要一个ClassModel,这里需要将 JSON 转 Swift Model Class......
未完待续。。。