adds core analyzer script which generates the core/channel/client method overview of a class

This commit is contained in:
logsol 2016-08-29 00:33:59 +02:00
parent c87997c774
commit 8d8a55cc8c

247
scripts/core_analyzer.js Normal file
View file

@ -0,0 +1,247 @@
/*
* This will generate a core/channel/client overview of a class
*
* usage:
* node scripts/core_analyzer.js [relative/path/class.js] -> relative path from core/client/channel split
*
* example:
* node scripts/core_analyzer.js GameObjects/Item.js
*
* example result:
*
* | CHANNEL | CORE | CLIENT
* |---------------------------------------|---------------------------------------|--------------------------------
* | | getBodyDef |
* | | getFixtureDef |
* | | createFixture |
* | | flip | flip
* | beingGrabbed | beingGrabbed |
* | beingReleased | beingReleased |
* | onCollisionChange | onCollisionChange |
* | | reposition |
* | | getGrabPoint |
* | | throw |
* | | accelerateBody |
* | | destroy | destroy
* | | | createMesh
* | | | render
* | getLastMovedBy | |
* | setLastMovedBy | |
* | isGrabbingAllowed | |
* | isReleasingAllowed | |
*
*/
var fs = require('fs');
var util = require('util');
var esprima = require('esprima');
var escodegen = require('escodegen');
var info = [];
var overview = {};
var generatorOption = {
format: {
indent: {
style: ' ',
base: 0,
adjustMultilineComment: true//false
},
newline: '\n',
space: ' ',
json: false,
renumber: false,
hexadecimal: false,
quotes: 'single',
escapeless: false,
compact: false,
parentheses: true,
semicolons: true,
safeConcatenation: true
},
moz: {
starlessGenerator: false,
parenthesizedComprehensionBlock: false,
comprehensionExpressionStartsWithAssignment: false
},
parse: null,
comment: true,
sourceMap: undefined,
sourceMapRoot: null,
sourceMapWithCode: false,
file: undefined,
directive: false,
verbatim: undefined
};
function readFile (path, category, fileName) {
//console.log("+++++ " + moduleName + " ++++++");
var contents = fs.readFileSync(path + "/" + category + "/" + fileName);
contents = contents.toString();
getMethods(path, fileName, contents, category);
}
function getMethods (path, fileName, contents, category) {
category = category.toLowerCase();
overview[category] = [];
var fullPath = path + "/" + fileName;
var moduleName = fileName.split(".js").join("");
var tree = esprima.parse(contents);
// find moduleId from return statement on module level
var module = tree.body[0].expression.arguments[1].body.body;
var moduleId = findModuleId(module);
if (!moduleId) {
info.push("could not find moduleId in: " + fullPath);
return;
}
if (moduleId == "Parent") {
info.push("not optimizing empty module (returning Parent) in: " + fullPath);
return;
}
// find constructor
var constructorPosition = findConstructorPosition(module, moduleId);
if (constructorPosition === false) {
info.push("could not find constructor in: " + fileName)
return;
}
var constructor = module[constructorPosition];
for (var j = 0; j < module.length; j++) {
var expression = module[j];
if (expression.type == "ExpressionStatement") {
if(expression.expression && expression.expression.right) {
if(expression.expression.right.type == "FunctionExpression") {
overview[category].push(expression.expression.left.property.name);
}
}
}
}
//console.log(escodegen.generate(tree, generatorOption));
}
function findModuleId (module) {
var moduleId = false;
for (var j = 0; j < module.length; j++) {
var expression = module[j];
//console.log(util.inspect(expression, { showHidden: true, depth: 4 }));
if (expression.type == "ReturnStatement") {
if(expression.argument.type == "Identifier") {
// for return Module;
moduleId = expression.argument.name;
break;
} else if (expression.argument.type == "NewExpression") {
// for return new Module;
moduleId = expression.argument.callee.name;
break;
} else {
info.push("Unexpected return type at module level. " + fullPath)
}
}
}
return moduleId;
};
function findConstructorPosition (module, moduleId) {
for (var j = 0; j < module.length; j++) {
var expression = module[j];
if (expression.type == "FunctionDeclaration" && expression.id.name == moduleId) {
return j;
}
}
return false;
}
var superOverview = {};
function display (category) {
var all = ["core", "client", "channel"];
var removeIndex = all.indexOf(category);
all.splice(removeIndex, 1);
for (var k in overview[category]) {
var name = overview[category][k];
if(superOverview.hasOwnProperty(name)) {
continue;
}
var first = all[0];
var second = all[1];
fv = 0 + (overview[first].indexOf(name) !== -1);
sv = 0 + (overview[second].indexOf(name) !== -1);
superOverview[name] = {};
superOverview[name][category] = 1;
superOverview[name][first] = fv;
superOverview[name][second] = sv;
superOverview[name]['count'] = 1 + fv + sv;
}
}
function show(){
var alle = ['channel', 'core', 'client'];
console.log("| CHANNEL | CORE | CLIENT");
console.log("|---------------------------------------|---------------------------------------|--------------------------------");
for (var method in superOverview) {
var line = "";
for (var i = 0; i < alle.length; i++) {
if (superOverview[method] && superOverview[method].hasOwnProperty(alle[i])) {
line += "| " ;
if(superOverview[method][alle[i]] === 1) {
line += method;
line += Array(39 - method.length).join(" ");
} else {
line += Array(39).join(" ");
}
} else {
}
}
console.log(line)
}
}
readFile("app/Game", "Core", process.argv[2]);
readFile("app/Game", "Channel", process.argv[2]);
readFile("app/Game", "Client", process.argv[2]);
display("core")
display("client")
display("channel")
console.log("\n")
show()
console.log("\n")