webamp/packages/webamp-modern/tools/extract-functions.js
Fathony Luthfillah 10555e093f
Set the 2nd modern iteration as only one on (modern) track. (#1166)
* yarn extract-object-types (run again)

* preparing to load Application.mi

* avoid error about using function ins strict mode.
turn this to "function" syntax to see the error/warn

* embed TrueTypeFont in one CSS

* add api: getAttribute

* reaching zero erro at devtool Console

* set color correctly.

* move compiler to new project

* take some yarn-scripts from sibling (modern-1)

* reconfigure objectData target path

* remove duplicated folder

* discontinuing the 1st iteration
captbaritone: it's probably time to del modern & ren modern-2: modern

* set the 2nd iteration as only one on track.
captbaritone: it's probably time to del modern & ren modern-2: modern

* bugfix test not working: path unavailable

* implement TODO

* reduce warning at import jzip

* solving Deploy: failed

* solving deploy failed
error: Unknown workspace "webamp-modern

* bugfix premateur call of this._font_id

* bugfix font-family : ''; prettier.

Co-authored-by: Fathony <fathony@smart-leaders.net>
2022-03-30 19:35:19 -07:00

111 lines
3.3 KiB
JavaScript
Executable file

#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const parse = require("../parser").default;
const JSZip = require("jszip");
const { getClass, getFunctionObject, getFormattedId } = require("../objects");
const glob = require("glob");
const CALL_OPCODES = new Set([24, 112]);
const SKIN_FILENAME_BLACKLIST = new Set(["Fuzzy_Muffins.wal"]);
function findWals(parentDir) {
return new Promise((resolve, reject) => {
glob("**/*.wal", { cwd: parentDir }, (err, files) => {
if (err) {
return reject(err);
}
resolve(files.map((filePath) => path.join(parentDir, filePath)));
});
});
}
function sumCountObjects(obj1, obj2) {
return Object.keys(obj2).reduce((summaryObj, key) => {
if (summaryObj[key] == null) {
summaryObj[key] = obj2[key];
} else {
summaryObj[key] += obj2[key];
}
return summaryObj;
}, Object.assign({}, obj1));
}
async function getCallCountsFromWal(absolutePath) {
const buffer = fs.readFileSync(absolutePath);
const zip = await JSZip.loadAsync(buffer);
const files = zip.file(/\.maki$/);
const buffers = await Promise.all(
files.map((file) => file.async("nodebuffer"))
);
return buffers.map(getCallCountsFromMaki).reduce(sumCountObjects, {});
}
function getCallCountsFromMaki(buffer) {
const maki = parse(buffer);
return maki.commands
.filter((command) => CALL_OPCODES.has(command.opcode))
.map((command) => {
const method = maki.methods[command.arg];
const classId = maki.classes[method.typeOffset];
const klass = getClass(classId);
if (klass == null) {
throw new Error(
`Unknown class ID: ${getFormattedId(classId)} aka ${classId} (raw)`
);
}
const parentClass = getFunctionObject(klass, method.name);
return `${parentClass.name}.${method.name.toLowerCase()}`;
})
.map((methodName) => ({ [methodName]: 1 }))
.reduce(sumCountObjects, {});
}
function setObjectValuesToOne(obj) {
const newObj = {};
Object.keys(obj).forEach((key) => {
if (obj[key] != null) {
newObj[key] = 1;
}
});
return newObj;
}
async function main(parentDir) {
const errors = [];
const paths = await findWals(parentDir);
const callCounts = [];
// Originally we moved to doing one skin at a time because we thougth it was
// causing memory issues, now we know it's not, but it's still faster to do
// one at a time for some reason. ¯\_(ツ)_/¯
for (const walPath of paths) {
try {
const fileName = path.basename(walPath);
if (SKIN_FILENAME_BLACKLIST.has(fileName)) {
continue;
}
console.error(`Working on ${walPath}`);
callCounts.push(await getCallCountsFromWal(walPath));
} catch (e) {
const errorLine = e.toString().split("\n")[0];
errors.push({ [errorLine]: 1 });
// TODO: Investigate these.
console.error(`Error getting calld data from ${walPath}`, e);
}
}
const totalCalls = callCounts.reduce(sumCountObjects);
const foundInSkins = callCounts
.map(setObjectValuesToOne)
.reduce(sumCountObjects);
if (errors.length) {
console.error(JSON.stringify(errors.reduce(sumCountObjects, {}), null, 2));
}
const result = { totalCalls, foundInSkins };
console.log(JSON.stringify(result, null, 2));
}
main("/Volumes/Mobile Backup/skins/skins/");