//import * as fs from "fs"; import * as path from "path"; import {repeat} from "./string-repeat"; import * as file from "./file"; import {RegExpExecArrayOptionalItems} from "./RegExpExecArrayOptionalItems"; import {TypeUtil} from "@anyhowstep/type-util"; export interface Import { alias : string, path : string, isSingle? : boolean } export interface LineArg { functionName : string, genericArg : string, functionArg : string, functionRet : string, functionArgNames : string[] } export interface GenerateArg { checkName : string, generated : boolean | undefined, imports : Import[], writeDirectory : string, lineCallback : (args : LineArg) => string[], } export function generate (args : GenerateArg) { const nestCount = args.checkName.split("/").length + 2; const unnest = repeat("../", nestCount); const lines = file.readSource(args.checkName, args.generated); const resultLines : string[] = []; for (let i of args.imports) { if (i.isSingle) { resultLines.push(`import {${i.alias}} from "${unnest}${i.path}";`) } else { resultLines.push(`import * as ${i.alias} from "${unnest}${i.path}";`) } } resultLines.push(""); for (let line of lines) { if (line.indexOf("export function ") == 0) { if (!/^export function check/.test(line)) { continue; } if (line.indexOf("Predicate") >= 0) { console.log("Skipping predicate..."); continue; } const match : null|RegExpExecArrayOptionalItems = /^export function check([a-zA-Z0-9_]+)(\<(.+)\>)? \((.+)\)( \: ([^\{]+))?/.exec(line); if (match == null) { throw new Error(`No match found for ${line}`); } const functionName : string|undefined = match[1]; const genericArg : string = TypeUtil.Coalesce(match[2], ""); const functionArg : string|undefined = match[4]; const functionRetRaw : string|undefined = match[6]; if (functionName == null) { throw new Error(`${args.checkName} : must have a function name`); } if (functionArg == null) { throw new Error(`${args.checkName} : ${functionName} must have arg`); } if (functionRetRaw == null) { throw new Error(`${args.checkName} : ${functionName} must have return type explicitly declared`); } const functionArgNamesRaw = functionArg.split(","); const functionArgNames : string[] = []; //All checkXXX() functions have two arguments at most functionArgNames.push(functionArgNamesRaw[0].split(":")[0].trim()); if (functionArgNamesRaw.length > 1) { functionArgNames.push(functionArgNamesRaw[1].split(":")[0].trim()); } const functionRetArr = functionRetRaw.split("|").map((r) => { r = r.trim(); if (r != "undefined") { if (r.indexOf(".") < 0) { r = `check.${r}`; } } return r; }); const toInsert = args.lineCallback({ functionName : functionName.trim(), genericArg : genericArg.trim(), functionArg : functionArg.trim(), functionRet : functionRetArr.join("|"), functionArgNames : functionArgNames }); resultLines.push(...toInsert); resultLines.push(""); } } const result = resultLines.join("\n"); const writePath = path.resolve(`${__dirname}/../main/generated/${args.writeDirectory}/${args.checkName}.ts`); file.writeSync(writePath, result); }