UNPKG

il2cppdump-mermaid

Version:

A small script to generate mermaid code from [Il2CppInspector](https://github.com/djkaty/Il2CppInspector) generated code that help you understand the relations

133 lines (105 loc) 3.36 kB
#!/usr/bin/env node import glob from 'glob'; import * as fs from 'fs'; import { default as scramjet } from 'scramjet'; const { StringStream } = scramjet; // Namespace relations import * as namespace_parser from './namespace_relations.js'; async function getNamespaceRelationsFromFile(file_path) { if(file_path.includes('global.cs')) { return null; } const lines = []; const stream = StringStream .pipeline(fs.createReadStream(file_path)) .lines() .while(line => { lines.push(line.trim()); return !line.startsWith('namespace'); }); await stream.run(); const result = namespace_parser.parse(lines.join('\n')); return `%% ${file_path} ${result} `; } // Class relations import * as class_parser from './class_relations.js'; function inferIsInterfaceFromName(name) { return name.startsWith("I") && name.length > 2 && name.substr(0, 2) === name.substr(0,2).toUpperCase(); } function normalizeGeneric(name) { return name.replace(/[<>]/g, '~').replace(/~([ ,\w]*)~~/, '_$1_~'); } function normalizeClassName(name) { return name.replace(/\./g, '_'); } async function getClassRelationsFromFile(file_path) { const lines = await StringStream .pipeline(fs.createReadStream(file_path)) .lines() .filter(line => line.includes(' class ') && !line.includes("where T")) .map(line => line.trim()) .map(line => { try { return class_parser.parse(line); } catch(err) { console.warn(line); return null; } }) .filter(Boolean) .map(def => { const { access_modifier, modifier, class_name: original_class_name, inheritances } = def; const possible_parent = inheritances && inheritances[0]; const parent = possible_parent && !inferIsInterfaceFromName(possible_parent) && normalizeGeneric(normalizeClassName(possible_parent)); const class_name = normalizeGeneric(normalizeClassName(original_class_name)); const class_def = `class ${class_name}`; const inherit_def = parent && `${class_name} --|> ${parent}` const interface_defs = inheritances .filter(inferIsInterfaceFromName) .map(normalizeGeneric) .map(name => `${class_name} ..|> ${name}`) const defs = [ // class_def, inherit_def, ...interface_defs ].filter(Boolean); return defs.join('\n') }) .filter(Boolean) .toArray(); return `%% ${file_path} ${lines.join('\n')} `; } const output_type_handler = { namespace: getNamespaceRelationsFromFile, class: getClassRelationsFromFile }; const output_type = process.argv[2] || 'namespace'; if(!Object.keys(output_type_handler).includes(output_type)) { throw new Error(`Invalid output type, must be one of ${Object.keys(output_type_handler).join(', ')}`); } glob("**/*.cs", {}, async (err, files) => { const processed = await Promise.all( files.map(output_type_handler[output_type]).filter(Boolean) ); fs.writeFileSync( `${output_type}_relations.md`, `%% Generated by il2cppdump-mermaid %% Author - [Houdou](https://github.com/Houdou) classDiagram direction LR `+ processed.join('\n'), 'utf8' ); });