mirror of
https://github.com/xuxiaobo-bobo/boda_jsEnv.git
synced 2025-04-22 06:37:32 +08:00
411 lines
25 KiB
JavaScript
411 lines
25 KiB
JavaScript
//babel库及文件模块导入
|
||
const fs = require('fs');
|
||
|
||
//babel库相关,解析,转换,构建,生产
|
||
const parser = require("@babel/parser");
|
||
const traverse = require("@babel/traverse").default;
|
||
const types = require("@babel/types");
|
||
const generator = require("@babel/generator").default;
|
||
//读取文件
|
||
let encode_file = "./test.js", decode_file = "./decode_result.proto";
|
||
if (process.argv.length > 2) {
|
||
encode_file = process.argv[2];
|
||
}
|
||
if (process.argv.length > 3) {
|
||
decode_file = process.argv[3];
|
||
}
|
||
//some function code
|
||
//判断类型
|
||
function get_id_type(id_type) {
|
||
switch (id_type) {
|
||
case "readString":
|
||
id_type = "string";
|
||
break;
|
||
case "readDouble":
|
||
id_type = "double";
|
||
break;
|
||
case "readInt32":
|
||
id_type = "int32";
|
||
break;
|
||
case "readInt64":
|
||
id_type = "int64";
|
||
break;
|
||
case "readFloat":
|
||
id_type = "float";
|
||
break;
|
||
case "readBool":
|
||
id_type = "bool";
|
||
break;
|
||
case "readPackedInt32":
|
||
id_type = "int32";
|
||
break;
|
||
case "readBytes":
|
||
id_type = "bytes";
|
||
break;
|
||
case "readEnum":
|
||
id_type = "readEnum";
|
||
break;
|
||
case "readPackedEnum":
|
||
id_type = "readPackedEnum";
|
||
break;
|
||
case "readUint64String":
|
||
id_type = "uint64";
|
||
break;
|
||
case "readInt64String":
|
||
id_type = "int64";
|
||
break;
|
||
case "readUint32":
|
||
id_type = "uint32";
|
||
break;
|
||
case "readUint64":
|
||
id_type = "uint64";
|
||
break;
|
||
case "readPackedInt64String":
|
||
id_type ='int64';
|
||
break;
|
||
}
|
||
return id_type
|
||
}
|
||
|
||
//首字母大写,处理
|
||
function titleCase(str) {
|
||
newStr = str.slice(0, 1).toUpperCase() + str.slice(1).toLowerCase();
|
||
return newStr;
|
||
}
|
||
|
||
//读取文件
|
||
let jscode = fs.readFileSync(encode_file, {encoding: "utf-8"});
|
||
//转换为ast树
|
||
let ast = parser.parse(jscode);
|
||
// console.log(ast)
|
||
text = 'syntax = "proto3";\n'
|
||
//处理message插件
|
||
const visitor =
|
||
{
|
||
//TODO write your code here!
|
||
AssignmentExpression(path, scope) {
|
||
// 外面大模型是没问题了,主要是里面细节
|
||
if (path.node.left.property) {
|
||
if (path.node.left.type == 'MemberExpression' &&
|
||
path.node.left.property.type == 'Identifier' &&
|
||
path.node.left.property.name == 'deserializeBinaryFromReader') {
|
||
//处理message名字
|
||
object_name = path.node.left.object.property.name
|
||
left_node = path.node.left
|
||
codename_list = generator(left_node).code.split('.');
|
||
codename_list.shift()
|
||
codename_list.pop()
|
||
object_name = codename_list.join('_');
|
||
// console.log(object_name);
|
||
text = text + 'message ' + object_name + '{\n'
|
||
//处理右边FunctionExpression语句
|
||
if (path.node.right.type == 'FunctionExpression') {
|
||
path.traverse({
|
||
//处理switch
|
||
SwitchStatement(path2) {
|
||
//case语句
|
||
cases_list = path2.node.cases
|
||
// console.log(generator(path2.node).code);
|
||
// try {
|
||
for (i = 0; i < path2.node.cases.length - 1; i++) {
|
||
location = cases_list[i].test.value
|
||
if (cases_list[i].consequent.length) {
|
||
if (cases_list[i].consequent[0].type == 'VariableDeclaration') {
|
||
//遇到new对象处理
|
||
if (cases_list[i].consequent[0].declarations[0].init.type == 'NewExpression') {
|
||
//获得type
|
||
node_code = cases_list[i].consequent[0].declarations[0].init
|
||
// console.log(generator(node_code).code)
|
||
node_code_list = generator(node_code).code.split('.')
|
||
node_code_list.shift()
|
||
id_type = node_code_list.join('_').replace('()', '')
|
||
// console.log(id_type);
|
||
//获得name,这部分有点问题,大家可以自行修改
|
||
try {
|
||
id_name = cases_list[i].consequent[1].expression.expressions[1].callee.property.name
|
||
} catch (e) {
|
||
id_name = cases_list[i].consequent[2].expression.callee.property.name
|
||
|
||
}
|
||
// console.log(id_name);
|
||
if (id_name.startsWith("set")) {
|
||
id_st = "";
|
||
} else if (id_name.startsWith("add")) {
|
||
id_st = "repeated";
|
||
} else {
|
||
// map类型,因为案例中用不到,所以这里省略
|
||
continue
|
||
}
|
||
id_name = id_name.substring(3, id_name.length).toLowerCase();
|
||
// console.log(id_name)
|
||
text = text + id_st + ' ' + id_type + ' ' + id_name + '=' + location + ';' + '\n'
|
||
|
||
|
||
}
|
||
//其他情况处理
|
||
else {
|
||
if (cases_list[i].consequent[0].declarations[0].init.callee)
|
||
id_type = cases_list[i].consequent[0].declarations[0].init.callee.property.name
|
||
if (cases_list[i].consequent[0].declarations[0].init.consequent || cases_list[i].consequent[0].declarations[0].init.alternate)
|
||
id_type = cases_list[i].consequent[0].declarations[0].init.consequent.callee.property.name
|
||
id_type = get_id_type(id_type)
|
||
// console.log(id_type);
|
||
if (cases_list[i].consequent[1].type == 'ForStatement')
|
||
id_name = cases_list[i].consequent[1].body.body[0].expression.callee.property.name
|
||
else if (cases_list[i].consequent[1].type == 'ExpressionStatement') {
|
||
if (cases_list[i].consequent[1].expression.expressions)
|
||
id_name = cases_list[i].consequent[1].expression.expressions[cases_list[i].consequent[1].expression.expressions.length - 1].callee.property.name
|
||
else
|
||
id_name = cases_list[i].consequent[1].expression.callee.property.name
|
||
}
|
||
|
||
if (id_name.startsWith("set")) {
|
||
id_st = "";
|
||
} else if (id_name.startsWith("add")) {
|
||
id_st = "repeated";
|
||
} else {
|
||
// map类型,因为案例中用不到,所以这里省略
|
||
continue
|
||
}
|
||
id_name = id_name.substring(3, id_name.length);
|
||
// console.log(id_name)
|
||
if (id_type == 'readEnum') {
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else if (id_type == 'readPackedEnum') {
|
||
id_st = 'repeated'
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else
|
||
text = text + id_st + ' ' + id_type + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
|
||
}
|
||
}
|
||
if (cases_list[i].consequent[0].type == 'ExpressionStatement') {
|
||
//一般处理
|
||
if (cases_list[i].consequent[0].expression.right.type == 'CallExpression') {
|
||
id_type = cases_list[i].consequent[0].expression.right.callee.property.name
|
||
// console.log(id_type)
|
||
id_type = get_id_type(id_type)
|
||
// console.log(id_type);
|
||
if (cases_list[i].consequent[1].type == 'ForStatement')
|
||
id_name = cases_list[i].consequent[1].body.body[0].expression.callee.property.name
|
||
else if (cases_list[i].consequent[1].type == 'ExpressionStatement') {
|
||
if (cases_list[i].consequent[1].expression.expressions)
|
||
id_name = cases_list[i].consequent[1].expression.expressions[cases_list[i].consequent[1].expression.expressions.length - 1].callee.property.name
|
||
else
|
||
id_name = cases_list[i].consequent[1].expression.callee.property.name
|
||
}
|
||
// console.log(id_name);
|
||
if (id_name.startsWith("set")) {
|
||
id_st = "";
|
||
} else if (id_name.startsWith("add")) {
|
||
id_st = "repeated";
|
||
} else {
|
||
// map类型,因为案例中用不到,所以这里省略
|
||
continue
|
||
}
|
||
id_name = id_name.substring(3, id_name.length).toLowerCase();
|
||
// console.log(id_name)
|
||
if (id_type == 'readEnum') {
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else if (id_type == 'readPackedEnum') {
|
||
id_st = 'repeated'
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else
|
||
text = text + id_st + ' ' + id_type + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
|
||
}
|
||
//遇到new对象处理
|
||
if (cases_list[i].consequent[0].expression.right.type == 'NewExpression') {
|
||
//转化成字符串对象处理
|
||
node_code = cases_list[i].consequent[0].expression.right.callee
|
||
node_code_list = generator(node_code).code.split('.')
|
||
node_code_list.shift()
|
||
id_type = node_code_list.join('_')
|
||
// console.log(id_type);
|
||
|
||
//获得name
|
||
id_name = cases_list[i].consequent[1].expression.expressions[1].callee.property.name
|
||
// console.log(id_name);
|
||
if (id_name.startsWith("set")) {
|
||
id_st = "";
|
||
} else if (id_name.startsWith("add")) {
|
||
id_st = "repeated";
|
||
} else {
|
||
// map类型,因为案例中用不到,所以这里省略
|
||
continue
|
||
}
|
||
id_name = id_name.substring(3, id_name.length).toLowerCase();
|
||
// console.log(id_name)
|
||
if (id_type == 'readEnum') {
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else if (id_type == 'readPackedEnum') {
|
||
id_st = 'repeated'
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else
|
||
text = text + id_st + ' ' + id_type + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
|
||
|
||
}
|
||
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|
||
|
||
},
|
||
////某音有的结构,遇到其他网站可以注释
|
||
IfStatement(path3) {
|
||
location = path3.node.test.left.value
|
||
if (path3.node.consequent.type === 'BlockStatement') {
|
||
if (path3.node.consequent.body[0].type === 'VariableDeclaration') {
|
||
// console.log(generator(path3.node).code)
|
||
//遇到new对象处理
|
||
if (path3.node.consequent.body[0].declarations[0].init.type == 'NewExpression') {
|
||
//获得type
|
||
node_code = path3.node.consequent.body[0].declarations[0].init
|
||
// console.log(generator(node_code).code)
|
||
node_code_list = generator(node_code).code.split('.')
|
||
node_code_list.shift()
|
||
id_type = node_code_list.join('_').replace('()', '')
|
||
// console.log(id_type);
|
||
//获得name,这部分有点问题,大家可以自行修改
|
||
try {
|
||
id_name = path3.node.consequent.body[0].expression.callee.property.name
|
||
|
||
} catch (e) {
|
||
id_name = path3.node.consequent.body[1].expression.expressions[1].callee.property.name
|
||
}
|
||
|
||
// console.log(id_name);
|
||
if (id_name.startsWith("set")) {
|
||
id_st = "";
|
||
} else if (id_name.startsWith("add")) {
|
||
id_st = "repeated";
|
||
} else {
|
||
// map类型,因为案例中用不到,所以这里省略
|
||
}
|
||
id_name = id_name.substring(3, id_name.length).toLowerCase();
|
||
// console.log(id_name)
|
||
if (id_type == 'readEnum') {
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else if (id_type == 'readPackedEnum') {
|
||
id_st = 'repeated'
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else
|
||
text = text + id_st + ' ' + id_type + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
|
||
|
||
} else {
|
||
id_type = path3.node.consequent.body[0].declarations[0].init.callee.property.name
|
||
id_type = get_id_type(id_type)
|
||
id_name = path3.node.consequent.body[1].expression.callee.property.name
|
||
if (id_name.startsWith("set")) {
|
||
id_st = "";
|
||
} else if (id_name.startsWith("add")) {
|
||
id_st = "repeated";
|
||
} else {
|
||
// map类型,因为案例中用不到,所以这里省略
|
||
}
|
||
id_name = id_name.substring(3, id_name.length).toLowerCase();
|
||
// console.log(id_name)
|
||
if (id_type == 'readEnum') {
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else if (id_type == 'readPackedEnum') {
|
||
id_st = 'repeated'
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else
|
||
text = text + id_st + ' ' + id_type + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
}
|
||
}
|
||
}
|
||
if (path3.node.consequent.type === 'ForStatement') {
|
||
id_type = path3.node.consequent.init.declarations[0].init.consequent.callee.property.name
|
||
id_type = get_id_type(id_type)
|
||
id_name = path3.node.consequent.body.expression.callee.property.name
|
||
// console.log(id_name);
|
||
if (id_name.startsWith("set")) {
|
||
id_st = "";
|
||
} else if (id_name.startsWith("add")) {
|
||
id_st = "repeated";
|
||
} else {
|
||
// map类型,因为案例中用不到,所以这里省略
|
||
}
|
||
id_name = id_name.substring(3, id_name.length).toLowerCase();
|
||
// console.log(id_name)
|
||
if (id_type == 'readEnum') {
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else if (id_type == 'readPackedEnum') {
|
||
id_st = 'repeated'
|
||
text = text + 'enum ' + titleCase(id_name) + ' {\n' + id_name + '_0=0;\n}\n' + id_st + ' ' + titleCase(id_name) + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
} else
|
||
text = text + id_st + ' ' + id_type + ' ' + id_name.toLowerCase() + '=' + location + ';' + '\n'
|
||
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
)
|
||
|
||
}
|
||
text = text + '}\n'
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
|
||
//处理enum对象插件
|
||
const visitor2 = {
|
||
AssignmentExpression(path) {
|
||
if (path.node.right.type === 'ObjectExpression' && path.node.left.type === 'MemberExpression' && path.node.right.properties.length) {
|
||
left_node = path.node.left
|
||
left_code = generator(left_node).code.split('.')
|
||
word = left_code.shift()
|
||
if (word === 'proto') {
|
||
enum_name = left_code.join('_')
|
||
// console.log(enum_name)
|
||
right_object_list = path.node.right.properties
|
||
right_str = ''
|
||
for (i = 0; i < right_object_list.length; i++) {
|
||
// console.log(right_object_list[i].key.name)
|
||
objet_name = right_object_list[i].key.name
|
||
objet_value = right_object_list[i].value.value
|
||
right_str = right_str + enum_name + '_' + objet_name + '=' + objet_value + ';\n'
|
||
}
|
||
text = text + 'enum ' + enum_name + '{\n' + right_str + '}' + '\n'
|
||
// console.log(right_code)
|
||
|
||
}
|
||
|
||
|
||
}
|
||
// console.log(generator(path.node).code)
|
||
}
|
||
}
|
||
|
||
|
||
//调用插件,处理源代码
|
||
|
||
// traverse(ast, visitor2)
|
||
// console.log('enum部分完成!!!')
|
||
// fs.writeFile('douyin_test_enum完成.proto', text, (err) => {});
|
||
|
||
traverse(ast, visitor);
|
||
console.log('message部分完成!!!')
|
||
// // fs.writeFile('douyin_test_message完成.proto', text, (err) => {});
|
||
//
|
||
//
|
||
// // console.log(text);
|
||
//
|
||
fs.writeFile(decode_file, text, (err) => {
|
||
});
|
||
|
||
|