Code
window.addEventListener("DOMContentLoaded", () => { const publicProps = /\bpublic\b.*?\s+?([_a-zA-Z0-9<>\[\]\?]+)\s+([_a-zA-Z0-9]+)[^\w]*/gm; //const publicProps = /\bpublic\b.*?\s+?([_a-zA-Z0-9<>\[\]\?]+)\s+([_a-zA-Z0-9]+?)\s*[;{=]/gm; const fallbackProps = /\b([_a-zA-Z0-9<>\[\]\?]+)\s+([_a-zA-Z0-9]+?)\s*[;{=]/gm; const reClass = /\b(class|interface|struct)\s*?([^\s]+)/gi; const reSingleLineComment = /(\/\/.*)/g; const reMultiLineComment = /\/\*(.|[\r\n])*?\*\//gm; const reEmptyOrBlankLines = /\n+\s*\n/gm; let className = "Unknown"; let targetClass = ""; const tab = "\t"; const line = "\r\n"; const getMatches = (re, str) => { let match, matches = []; while (match = re.exec(str)) { matches.push(match); } return matches; }; const filterProps = (prop) => { const reserved = ["void", "return", "class", "struct", "enum", "using", "var"]; return reserved.indexOf(prop.type) === -1; }; const convertGetSet = (prop) => { const p = prop.name; return `public ${prop.type} ${p} { get; set; }`; }; const convertInitializer = (prop, prefix) => { const p = prop.name; let c = prop.last ? "" : ","; return `${p} = ${prefix}${p}${c}`; // ${prop.type} }; const convertAssignment = (prop, prefix, prefix2) => { const p = prop.name; return `${prefix}${p} = ${prefix2}${p};`; // ${prop.type} }; const mapTabs = (arr, tabCount) => { const tabs = tab.repeat(tabCount); return Array.from(arr).map(a => tabs + a); } const mapProps = (match, i, arr) => { return { type: match[1], name: match[2], last: arr.length - 1 === i }; }; const convertAll = (str) => { str = String(str).replace(reSingleLineComment, ""); str = String(str).replace(reMultiLineComment, ""); str = String(str).replace(reEmptyOrBlankLines, "\n"); console.log(str); let props = getMatches(publicProps, str).map(mapProps).filter(filterProps); if (props.length < 1) { props = getMatches(fallbackProps, str).map(mapProps).filter(filterProps); } console.table(props); console.log(JSON.stringify(props.reduce((x, p) => { x[p.name] = p.type; return x; }, {}), null, 4)); const props1 = mapTabs(props.map(p => convertGetSet(p)), 1); const props2 = mapTabs(props.map(p => convertAssignment(p, "dest.", "src.")), 1); const props3 = mapTabs(props.map(p => convertInitializer(p, "src.")), 2); const props4 = mapTabs(props.map(p => convertAssignment(p, "", "src.")), 1); const mapFrom = mapTabs([ `public static ${targetClass} FromDomain(${className} src, ${targetClass} dest = null) => FromDomainExt(src, dest);`, `public static T FromDomainExt<T>(${className} src, T dest = null) where T: ${targetClass}, new()`, `{`, tab + `if (src == null) return null;`, tab + `if (dest == null) dest = new T();`, ...props2, tab + `return dest;`, `}` ], 1); const mapTo = mapTabs([ `public static ${className} ToDomain(${targetClass} src, ${className} dest = null) => ToDomainExt(src, dest);`, `public static T ToDomainExt<T>(${targetClass} src, T dest = null) where T: ${className}, new()`, `{`, tab + `if (src == null) return null;`, tab + `if (dest == null) dest = new T();`, ...props2, tab + `return dest;`, `}` ], 1); // const mapCopyFrom = mapTabs([ // `public void CopyFrom(${className} src)`, // `{`, // ...props4, // `}` // ], 1); // const mapCopyTo = mapTabs([ // `public static ${className} CopyTo(this ${className} src, ${targetClass} dest)`, // `{`, // ...props2, // `}` // ], 1); const classMapper = mapTabs([ `public class ${targetClass}`, `{`, ...props1, "", ...mapFrom, ...mapTo, // ...mapCopyFrom, // ...mapCopyTo, `}` ], 0); const mapperClassSrc = classMapper.join(line); const toDomainMapper = mapTabs([ `public static ${className} ToDomain(this ${targetClass} src) {`, `\tif (src == null) return null;`, `\treturn new ${className}() {`, ...props3, `\t};`, `}` ], 1); const fromDomainMapper = mapTabs([ `public static ${targetClass} FromDomain(this ${className} src) {`, `\tif (src == null) return null;`, `\treturn new ${targetClass}() {`, ...props3, `\t};`, `}` ], 1); const extensionMapperSrc = mapTabs([ `public static class ${targetClass}Extensions`, `{`, ...toDomainMapper, "", ...fromDomainMapper, `}` ], 0).join(line); const entityConfigure = mapTabs([ `public void Configure(EntityTypeBuilder<${targetClass}> entityTypeBuilder)`, `{`, `\tentityTypeBuilder.ToTable("${className}");`, `\tentityTypeBuilder.HasKey(x => x.${props[0].name});`, ...props.map(p => `\tentityTypeBuilder.Property(x => x.${p.name});`), `}` ], 1); const entityMapperSrc = mapTabs([ `public class ${targetClass}Map : IEntityTypeConfiguration<${targetClass}>`, `{`, ...entityConfigure, `}` ], 0).join(line); return [mapperClassSrc, extensionMapperSrc, entityMapperSrc].join("\n"); }; const run = () => { const input = document.querySelector("#input").value; className = (reClass.exec(input) || [])[2] || null; if (className) { targetClass = `Dm${className}`; const output = convertAll(input); document.querySelector("#output").value = output; } }; document.querySelector("#btnRun").addEventListener("click", run); });
159040cookie-checkC# Mapper