UNPKG

@wuapi/generator

Version:
307 lines (298 loc) 13.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const essential_1 = require("@wuapi/essential"); const plugin_base_1 = require("./plugin_base"); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const brace_1 = require("./brace"); const dedent_1 = __importDefault(require("dedent")); const lodash_1 = __importDefault(require("lodash")); /** * Swift code plugin. */ class SwiftPlugin extends plugin_base_1.BasePlugin { /** * Returns the description of this plugin. */ getDescription() { return { name: "swift", abbreviation: "s", version: "1.0.0", description: "Generate Swift code.", arguments: [], }; } process(project, outputDir, args) { new SwiftProcessor(this, project, outputDir, args).process(); } } exports.default = SwiftPlugin; /** * The Swift project processor */ class SwiftProcessor extends plugin_base_1.ProjectProcessor { /** * Write entity */ writeEntity(b, pth, entity) { const self = this; // function calcSuffix(extra) { let unsolved = entity.getGenericUnsolved(self.project); if (extra) { unsolved = lodash_1.default.concat(unsolved, [extra]); } return (unsolved.length > 0) ? `<${unsolved.join(", ")}>` : ""; } // function calcExtSuffix(extra) { let punsolved = entity.parent?.asEntityOf(self.project)?.getGenericUnsolved(self.project) ?? []; let result = []; punsolved.forEach((name) => { let solved = entity.genericMap[name]; let item = (solved) ? genericTypeName(solved.type) : name; result.push(item); }); if (extra) { result.push(extra); } return (result.length > 0) ? `<${result.join(", ")}>` : ""; } // function memberTypeName(type) { switch (type.member.type) { case "TBoolean": return "Bool"; case "TInteger": return "Int"; case "TLong": return "Int64"; case "TID": return "Int64"; case "TDouble": return "Double"; case "TString": return "String"; case "TURL": return "String"; case "TDateTime": return "String"; case "TSSMap": return "[String: String]"; case "TEnum": return type.member.enu.name; case "TObject": return type.member.entity.name; case "TUnknown": return type.member.unknown; case "TList": throw Error("List can not contain list!"); default: throw new Error(`Unknown list type "${type.member.type}" in "${pth.module}/${pth.name}"`); } } // function genericTypeName(type) { switch (type.type) { case "TBoolean": return "Bool"; case "TInteger": return "Int"; case "TLong": return "Int64"; case "TID": return "Int64"; case "TDouble": return "Double"; case "TString": return "String"; case "TURL": return "String"; case "TDateTime": return "String"; case "TSSMap": return "[String: String]"; case "TEnum": return type.enu.name; case "TObject": return type.entity.name; case "TList": return memberTypeName(type); default: throw new Error(`Unknown generic type "${type.type}" in "${pth.module}/${pth.name}"`); } } // function generateField(name, f) { // b(f.comments.toLineComment() if (f.fixedValue) { switch (f.type.type) { case "TBoolean": return `public var ${name}: Bool = ${f.fixedValue};`; case "TInteger": return `public var ${name}: Int = ${f.fixedValue};`; case "TLong": return `public var ${name}: Int64 = ${f.fixedValue};`; case "TID": return `public var ${name}: Int64 = ${f.fixedValue};`; case "TDouble": return `public var ${name}: Double = ${f.fixedValue};`; case "TString": return `public var ${name}: String = "${f.fixedValue}";`; case "TURL": return `public var ${name}: String = "${f.fixedValue}";`; case "TDateTime": return `public var ${name}: String = "${f.fixedValue}";`; default: throw Error(`Field '${name}' in "${pth.module}/${pth.name}" with type ${f.type.type} can NOT have fixed value!`); } } else if (f.isOptional) { switch (f.type.type) { case "TBoolean": return `public var ${name}: Bool? = nil`; case "TInteger": return `public var ${name}: Int? = nil`; case "TLong": return `public var ${name}: Int64? = nil`; case "TID": return `public var ${name}: Int64? = nil`; case "TDouble": return `public var ${name}: Double? = nil`; case "TString": return `public var ${name}: String? = nil`; case "TURL": return `public var ${name}: String? = nil`; case "TDateTime": return `public var ${name}: String? = nil`; case "TSSMap": return `public var ${name}: [String: String]? = nil`; case "TEnum": return `public var ${name}: ${f.type.enu.name}? = nil`; case "TObject": return `public var ${name}: ${f.type.entity.name}? = nil`; case "TList": return `public var ${name}: [${memberTypeName(f.type)}]? = nil`; case "TUnknown": return `public var ${name}: ${f.type.unknown}? = nil`; default: throw Error(`Type "${f.type.type}" of Field "${name}" in "${pth.module}/${pth.name}" is invalid.`); } } else { switch (f.type.type) { case "TBoolean": return `public var ${name}: Bool = false`; case "TInteger": return `public var ${name}: Int = 0`; case "TLong": return `public var ${name}: Int64 = 0`; case "TID": return `public var ${name}: Int64 = 0`; case "TDouble": return `public var ${name}: Double = 0`; case "TString": return `public var ${name}: String = ""`; case "TURL": return `public var ${name}: String = ""`; case "TDateTime": return `public var ${name}: String = ""`; case "TSSMap": return `public var ${name}: [String: String] = [:]()`; case "TEnum": { let fe = f.type; return `public var ${name}: ${fe.enu.name} = ${fe.enu.name}.${fe.enu.asEnumOf(self.project).first()}`; } case "TObject": { let fo = f.type; return `public var ${name}: ${fo.entity.name} = ${fo.entity.name}()`; } case "TList": { let fl = f.type; if (fl.member.type == "TUnknown") { return `public var ${name}: [${fl.member.unknown}] = [${fl.member.unknown}]()`; } else { return `public var ${name}: [${memberTypeName(fl)}] = [${memberTypeName(fl)}]()`; } } case "TUnknown": throw Error(`Field '${name}' in "${pth.module}/${pth.name}" can NOT be unknown!`); default: throw Error(`Type "${f.type.type}" of Field "${name}" in "${pth.module}/${pth.name}" is invalid.`); } } } // b(toBlockComment(entity)) let suffix = ""; let pname = ""; let extSuf = ""; switch (entity.type) { case essential_1.$EntityType.REQUEST: { let resName = entity.response?.name; pname = entity.parent?.name ?? 'AbsReq'; suffix = calcSuffix(entity.isAbstract ? "R: AbsRes" : undefined); extSuf = calcExtSuffix(entity.isAbstract ? "R" : (resName ?? undefined)); break; } case essential_1.$EntityType.RESPONSE: { pname = entity.parent?.name ?? 'AbsRes'; suffix = calcSuffix(); extSuf = calcExtSuffix(); break; } case essential_1.$EntityType.OBJECT: { pname = entity.parent?.name ?? 'AbsBase'; suffix = calcSuffix(); extSuf = calcExtSuffix(); break; } } b.bra(`public class ${pth.name}${suffix}: ${pname}${extSuf}`).add((b) => { if (entity.type == essential_1.$EntityType.REQUEST && !entity.isAbstract) { b((0, dedent_1.default) ` public override func obtainPath() -> String { return "${entity.path}" } `); b((0, dedent_1.default) ` public override func obtainMethod() -> String { return "${entity.method}" } `); } b((0, dedent_1.default) ` public required init?(map: Map) { super.init(map: map) } public required init(){ super.init() }\n `); lodash_1.default.forIn(entity.fieldsLocal, (f, name) => { b(generateField(name, f)); }); b.bra("public override func mapping(map: Map)").add((b) => { b("super.mapping(map: map)"); lodash_1.default.forIn(entity.fieldsLocal, (f, name) => { // TODO: filter out generics ? let realname = f.realname ?? pth.name; b(`${pth.name} <- map["${realname}"]`); }); }); }); } /** * Write enum class */ writeEnum(b, pth, enu) { b.bra(`public enum ${pth.name}: String`).add((b) => { // enu.intMap.keys.sorted().forEach { enu.flat().forEach(({ name, item }) => { b(`case ${name}`); }); b(""); b.bra("public func code() -> Int").add((b) => { b.bra("switch self").add((b) => { enu.flat().forEach(({ name, item }) => { b(`case .${name}: return ${item.value}`); }); }); }); }); } /** * Process the project. */ process() { fs_1.default.rmSync(this.rootDir, { recursive: true, force: true }); fs_1.default.mkdirSync(this.rootDir, { recursive: true }); const filePath = this.rootDir + path_1.default.sep + `${this.project.name}Entities.swift`; const file = fs_1.default.openSync(filePath, 'w'); fs_1.default.writeFileSync(file, (0, brace_1.flatBra)("").add((b) => { b((0, dedent_1.default) ` public class AbsBase: NSObject, Mappable { public required init?(map: Map){} public override required init(){} public func mapping(map: Map){} public func obtainExtra() -> [String:String] { return [String:String]() } } public class AbsReq<T: AbsRes>: AbsBase { public func obtainPath() -> String{ return "" } public func obtainMethod() -> String {return "" } public func obtainRes(json: String) -> T? { return Mapper<T>().map(JSONString: json) } public required init?(map: Map) { super.init(map: map) } public required init() { super.init() } public override func mapping(map: Map) { super.mapping(map: map) } } public class AbsRes: AbsBase { public func obtainSuccessCode() -> Int { return 200 } public required init?(map: Map) { super.init(map: map) } public required init() { super.init() } public override func mapping(map: Map) { super.mapping(map: map) } } `); this.project.flatEntities().forEach(({ path, entity }) => { this.writeEntity(b, path, entity); }); this.project.flatEnums().forEach(({ path, enu }) => { this.writeEnum(b, path, enu); }); }).toString()); } }