Files
MMMemory/toSwift
Михаил Капелько 56cac34baf d
2023-06-19 19:38:51 +03:00

142 lines
3.1 KiB
JavaScript
Executable File

#!/usr/bin/env node
if (process.argv.length < 4) {
console.error("Usage: toSwift SRC DST");
process.exit(1);
}
var fs = require("fs");
let fileSrc = process.argv[2];
let fileDst = process.argv[3];
let globalReplacements = {
"function": "func",
"number": "Float",
"Number": "Float",
"):": ") ->",
"interface": "protocol",
"})": "}", // forEach
".push(": ".append(", // array
};
console.log(`Converting '${fileSrc}' to '${fileDst}'`);
var linesDst = [];
let linesSrc = fs.readFileSync(fileSrc).toString().split(/\r?\n/);
for (let i in linesSrc) {
let ln = linesSrc[i];
linesDst.push(convert(ln));
}
let contentsDst = linesDst.join("\r\n");
fs.writeFileSync(fileDst, contentsDst);
// Functions making decisions.
function convert(line) {
var result = line;
for (let src in globalReplacements) {
let dst = globalReplacements[src];
result = result.replaceAll(src, dst);
}
result = protocolReplace(result);
result = typeArrayReplace(result);
result = forEachReplace(result);
result = recordReplace(result);
return result;
}
// x.forEach(y => { -> x.forEach { y in
function forEachReplace(line) {
if (!line.includes("forEach")) {
return line;
}
let partsFE = line.split("forEach");
let identifier = partsFE[0];
let closure = partsFE[1];
let partsC = closure.split(" => ");
let bracketAndVar = partsC[0];
let bracket = partsC[1];
let variable = bracketAndVar.substring(1);
let result = `${identifier}forEach { ${variable} in`;
return result;
}
var isProtocol = false;
// interface -> protocol
function protocolReplace(line) {
if (line.includes("protocol")) {
isProtocol = true;
}
if (line == "}") {
isProtocol = false;
}
if (!isProtocol) {
return line;
}
var result = line;
if (isProtocol) {
result = protocolReplaceVariable(result);
}
return result;
}
// a: Number -> var a: Float { get }
function protocolReplaceVariable(line) {
let parts = line.split(": ");
if (parts.length == 2) {
let type = parts[1];
let name = parts[0].trim();
let spaceLength = parts[0].length - name.length;
let spaces = " ".repeat(spaceLength);
return `${spaces}var ${name}: ${type} { get }`;
}
return line;
}
// Record<TypeA, TypeB> -> [TypeA: TypeB]
// Record<TypeA, TypeB> = {} -> [TypeA: TypeB] = [:]
function recordReplace(line) {
if (!line.includes("Record")) {
return line;
}
let partsR = line.split("Record<");
let typesAndEnding = partsR[1];
let partsT = typesAndEnding.split(">");
let types = partsT[0];
let ending = partsT[1];
let swiftTypes = types.split(", ");
let was = `Record<${swiftTypes[0]}, ${swiftTypes[1]}>`;
let now = `[${swiftTypes[0]}: ${swiftTypes[1]}]`;
var result = line;
result = result.replace(was, now);
result = result.replace("] = {};", "] = [:]");
return result;
}
// Type[] -> [Type]
function typeArrayReplace(line) {
let parts = line.split(" ");
for (var i in parts) {
let part = parts[i];
if (
part != "[]" &&
part.endsWith("[]")
) {
let type = part.substring(0, part.length - 2)
let swiftType = `[${type}]`;
return line.replace(part, swiftType);
}
}
return line;
}