java 生成swift_如何将JavaScript转化成Swift?(一)

最近遇到了一个诡异的需求:

将一个弱类型语言JavaScript转化成强类型语言Swift

方案一:

强转,将JavaScript的语法和Swift的语法一一对应

在Js中 一个方法的关键词是 function 在Swift中是 func,我们遍历一下Js代码,将所有的 function 转化成 func

嗯。。。 感觉太傻了。。。没有一点作为一个程序猿的追求

方案二:

将Js转化成AST,将Js的AST转化成Swift的AST,然后再转回Swift

嗯。。。这个貌似牛逼哄哄,但是遇到了几个难点:

1、Js的AST和Swift的AST很难找到对应关系

JavaScript中定义一个a变量:

var a = 1

Swift中定义一个a变量:

var a = 1

他们的AST分别如下:

1950dcbb44a53022fbbdb6389a900dfa.png

b031b784f6d60a56576fd7ecacb617f0.png

两者的语法描述一模一样,但是AST却相差很多,很难找到差异性

2、JavaScript中通过 escodegen 这个库 将AST重新生成为源码,但是在Swift和Java中并未找到相应的官方库或者第三方库来进行转化

3、JavaScript中有ES5、ES6,我们可以编写ES6的语法然后通过Bebal将ES6翻译成ES5,用到就是 JavaScript 和 AST 之间的相互转换,但是Swift并中没有类似的需求,所以相应的资料代码极少

方案三:

将Js的AST转化成Swift

既然不能将Swift的AST转化成Swift,可不可以将Js的AST转化成Swift呢?

如何操作?:

这里借鉴了JS Parser的三板斧

1.通过 esprima 把源码转化为AST

2.通过 estraverse 遍历并更新AST

3.通过 escodegen 将AST重新生成源码

简单说一下原理:

首先通过 esprima 将js 源码翻译成 AST,

通过 estraverse 遍历AST 补充一些特征(比如类型)

修改 escodegen 源码,生成Swift源码

修改 escodegen 源码

新建一个Js的项目,安装 esprima、escodegen依赖,

新建 test.js 需要解析的js代码:

function testFunc() {

var a = 1

var b = "1"

var c = false

if (a<20) {

b = "Good day";

}

console.log(b)

var car = {type:"Fiat", model:500, color:"white"};

console.log(car.type)

}

复制代码

新建 swift.js 用来读取 test.js 代码,生成 test.swift 文件:

const esprima = require('esprima');

const escodegen = require("escodegen");

var fs = require("fs")

// 读取test.js代码

var data = fs.readFileSync('test.js');

let code = data.toString()

// 解析js的语法

let tree = esprima.parseScript(code);

// 解析ast

let transformCode = escodegen.generate(tree);

// 生成swift文件

fs.writeFile('test.swift', transformCode, function(err) {

if (err) {

return console.error(err);

}

});

复制代码

进行编译。。。

node swift.js

下面开始修改 escodegen 里面的 escodegen.js 文件

将 function 替换成 func

FunctionDeclaration: function (stmt, flags) {

return [

generateAsyncPrefix(stmt, true),

'function',

generateStarSuffix(stmt) || noEmptySpace(),

stmt.id ? generateIdentifier(stmt.id) : '',

this.generateFunctionBody(stmt)

];

},

复制代码

这段代码是用来处理 function 节点,我们只需要将 function 修改成 func 即可,很简单!

Js是弱类型,如何判断类型?

VariableDeclarator: function (stmt, flags) {

var itemFlags = (flags & F_ALLOW_IN) ? E_TTT : E_FTT;

console.log("+++++++++++++++++ 执行 VariableDeclarator+++++++++++++++++")

// 增加数据类型

// console.log(stmt.mold.name)

if (stmt.init) {

if (stmt.mold.name) {

return [

this.generateExpression(stmt.id, Precedence.Assignment, itemFlags),

space,

'=',

space,

this.generateExpression(stmt.init, Precedence.Assignment, itemFlags)

];

}

];

}

复制代码

这是处理变量的一个方法, 这段代码的返回结果是:a = 1 , 我们只需要在 a 前面加上 类型即可,这里用 Js的 typeof 方法进行判断,然后将 number、string、boolean 和swift 的Int、String、Bool进行映射

如何将 console.log 修改成 print

// 进行字符串替换

for (let i = 0; i < result.length; i++) {

const element = result[i];

if (element.indexOf("console.log")!=-1) {

result[i] = element.replace(/console.log/, "print")

}

}

复制代码

比较简单粗暴。。。

如何将Js的对应翻译成 Swift的对象?

这个稍微复杂,因为Js弱类型的特性,他不需要额外去写一个类定一个对象,但是Swift需要,所以这里我们需要读取Js的对象,然后生成一个类

在 Js 中 描述一个对象

var car = {type:"Fiat", model:500, color:"white"}

复制代码

在Swift中描述一个对象

class Car: NSObject {

var type: String = ""

var model: Int = 0

var color: String = ""

init(type: String, model: Int, color: Int) {

self.type = type

self.model = model

self.color = color

}

}

let car = Car(type: "Fiat", model: 500, color: "white")

复制代码

在 ObjectExpression 方法中 可以通过

if (expr.properties) {

let properties = expr.properties

for (let i = 0; i < properties.length; i++) {

const element = properties[i];

// 生成对应的文件

console.log(element.key.name)

}

}

复制代码

将 var car = {type:"Fiat", model:500, color:"white"} 中的type、model、color读取到,然后生成对应的Swift文件

剩下的就是将

var car = {type:"Fiat", model:500, color:"white"}

复制代码

替换成

let car = Car(type: "Fiat", model: 500, color: "white")

复制代码

只需要生成对象的时候记录一下类名,将 ‘{’ 替换成 ‘Car(’ ,将 ‘)’ 替换成 ‘}’即可

生成对象的代码:

// 生成类名

let className = getClassName(expr)

var swiftObject = 'class ' + className + ': NSObject { \n'

if (expr.properties) {

let properties = expr.properties

for (let i = 0; i < properties.length; i++) {

const element = properties[i];

// 生成对应的文件

swiftObject += space + space + "var " + element.key.name + ': ' + typeOfSwift(element.value.value) + '\n'

}

}

swiftObject += '}'

fs.writeFile('./Swift_Code/Model/' + className + '.swift', swiftObject, function(err) {

console.log(err)

if (err) {

return console.error(err);

}

});

复制代码

成果

完成了上述的翻译就可以完美的将 test.js 代码翻译成 test.swift 啦

func testFunc() {

var a:Int = 1;

var b:String = '1';

var c:Bool = false;

if (a < 20) {

b = 'Good day';

}

print(b);

var car = Car(

type: 'Fiat',

model: 500,

color: 'white'

);

print(car.type);

}

复制代码

for循环如何翻译?Js的网络请求如何翻译成Swift

未完待续。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaSwift是不同的编程语言,分别用于开发不同的应用程序。Java主要用于开发后端和企业级应用程序,而Swift主要用于开发iOS和Mac应用程序。 如果您想要在Java生成Swift报文,可以使用以下方法。 1. 使用第三方库:您可以在Java中使用第三方库来生成Swift报文。例如,可以使用JSON库,如Gson或Jackson,将Java对象换为JSON格式的字符串。然后,您可以将生成JSON字符串发送给Swift端。在Swift中,您可以使用`JSONSerialization`类将JSON字符串换为Swift对象。 2. 使用网络请求库:如果您需要通过网络发送Swift报文,您可以使用Java中的网络请求库,如HttpURLConnection或OkHttp,将Java对象换为JSON字符串并发送给服务器。然后在Swift端,您可以使用网络请求库,如Alamofire,从服务器接收和解析JSON响应。 3. 使用自定义协议:您还可以定义一种自定义的协议或数据格式来生成Swift报文。例如,您可以使用XML或Protocol Buffers格式定义报文结构,并在Java中使用相应的库将Java对象换为该格式。然后在Swift端,您可以使用相应的库将接收到的报文解析为Swift对象。 总结而言,您可以使用第三方库、网络请求库或自定义协议等方法,在Java生成Swift报文。但请注意,这并不是直接将Java代码换为Swift代码的过程,而是将Java对象换为适合Swift端处理的数据格式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值