C# Mapper

Date: 2018-11-19

Code

window.addEventListener("DOMContentLoaded", () => {
    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" ];
        if (reserved.indexOf(prop.type) === -1) {
            return true;
        }
    };
    const convertInitializer = (prop, prefix) => {
        let p = prop.name;
        let c = prop.last ? "" : ",";
        return `${p} = ${prefix}${p}${c}`; // ${prop.type}
    };
    const convertAssignment = (prop, prefix, prefix2) => {
        let 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 => convertInitializer(p, "")), 2);
        const props2 = mapTabs(props.map(p => convertAssignment(p, "target.", "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([
            `internal static ${targetClass} FromDomain(${className} src)`,
            `{`,
            tab + `if (src == null) return null;`,
            tab + `return new ${targetClass} {`,
            ...props3,
            tab + `};`,
            `}`
        ], 1);
        const mapTo = mapTabs([
            `internal static ${className} ToDomain(${targetClass} src)`,
            `{`,
            tab + `if (src == null) return null;`,
            tab + `return new ${className} {`,
            ...props3,
            tab + `};`,
            `}`
        ], 1);
        const mapCopyFrom = mapTabs([
            `internal void CopyFrom(${className} src)`,
            `{`,
            ...props4,
            `}`
        ], 1);
        const mapCopyTo = mapTabs([
            `internal static ${className} CopyTo(this ${className} src, ${targetClass} target)`,
            `{`,
            ...props2,
            `}`
        ], 1);
        const classMapper = mapTabs([
            `public static class ${targetClass}`,
            `{`,
            ...mapFrom,
            ...mapTo,
            ...mapCopyFrom,
            ...mapCopyTo,
            `}`
        ], 0);
        return classMapper.join(line);
    };
    const run = () => {
        const input = document.querySelector("#input").value;
        className = (reClass.exec(input) || [])[2] || null;
        if (className) {
            targetClass = `Vm${className}`;
            const output = convertAll(input);
            document.querySelector("#output").value = output;
        }
    };
    document.querySelector("#btnRun").addEventListener("click", run);
});

15900cookie-checkC# Mapper