thomasfn

AnalyseEvents.js

Jun 9th, 2015
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. var fs = require("fs");
  3. var path = require("path");
  4. var tokenizer = require("js-tokenizer");
  5.  
  6. // Get directory
  7. var targetDir = process.argv[2];
  8. var outputFile = targetDir + "/events_map.txt";
  9.  
  10. var fileCount = 0, dirCount = 0, errCount = 0;
  11.  
  12. var globalEventMap = {};
  13.  
  14. var filesToParse = [];
  15.  
  16. $ = {};
  17. $.each = function(obj, func)
  18. {
  19.   var keys = Object.keys(obj);
  20.   keys.sort();
  21.   for (var i = 0; i < keys.length; i++)
  22.   {
  23.     var key = keys[i];
  24.     func(key, obj[key]);
  25.   }
  26. };
  27.  
  28. function scanJS(path, name)
  29. {
  30.   fileCount++;
  31.  
  32.   var str = fs.readFileSync(path, { "encoding": "UTF8" });
  33.   var tokenArray;
  34.   try
  35.   {
  36.     tokenArray = tokenizer(str);
  37.   }
  38.   catch (err)
  39.   {
  40.     console.warn("Could not tokenise '" + path + "'... " + err.stack);
  41.     errCount++;
  42.     return;
  43.   }
  44.  
  45.   //console.log(something);
  46.  
  47.   // RS.Events.publish(RS.Felt.Something.MyEvent);
  48.   // 'RS', '.', 'Events', '.', 'publish', '(', ..., ',', ..., ')', ';'
  49.  
  50.   // Find the start of a event library call
  51.   for (var i = 0; i < tokenArray.length - 6; i++)
  52.   {
  53.     if (tokenArray[i] === 'RS'
  54.       && tokenArray[i+1] === '.'
  55.       && tokenArray[i+2] === 'Events'
  56.       && tokenArray[i+3] === '.')
  57.     {
  58.       // Identify publish or subscribe
  59.       if (tokenArray[i+4] === 'publish'
  60.       && tokenArray[i+5] === '(')
  61.       {
  62.         var eventName = findEventName(tokenArray, i+6);
  63.         var eventMap = globalEventMap[eventName] || (globalEventMap[eventName] = {});
  64.         var eventPublishers = eventMap["publishers"] || (eventMap["publishers"] = {});
  65.         eventPublishers[name] = (eventPublishers[name] || 0) + 1;
  66.       }
  67.       else if (tokenArray[i+4] === 'subscribe'
  68.       && tokenArray[i+5] === '(')
  69.       {
  70.         var eventName = findEventName(tokenArray, i+6);
  71.         var eventMap = globalEventMap[eventName] || (globalEventMap[eventName] = {});
  72.         var eventSubscribers = eventMap["subscribers"] || (eventMap["subscribers"] = {});
  73.         eventSubscribers[name] = (eventSubscribers[name] || 0) + 1;
  74.       }
  75.     }
  76.   }
  77.  
  78.   //console.log(str.length);
  79. }
  80.  
  81. function scanDir(dir)
  82. {
  83.   dirCount++;
  84.   var items = fs.readdirSync(dir);
  85.   for (var i = 0; i < items.length; i++)
  86.   {
  87.     var item = items[i];
  88.     var absPath = dir + "/" + item
  89.     var ext = path.extname(item);
  90.     if (ext == ".js")
  91.     {
  92.       //scanJS(absPath, item);
  93.       //return;
  94.       filesToParse.push({ "name": item, "path": absPath });
  95.     }
  96.     else
  97.     {
  98.       var stat = null;
  99.       try
  100.       {
  101.         stat = fs.lstatSync(absPath);
  102.       }
  103.       catch (err) {};
  104.  
  105.       if (stat && stat.isDirectory())
  106.       {
  107.         scanDir(absPath);
  108.       }
  109.     }
  110.   }
  111. };
  112.  
  113. function resolveNameConflicts()
  114. {
  115.   var conflictCount = -1;
  116.   var resolveAttempts = 0;
  117.   while (conflictCount != 0)
  118.   {
  119.     resolveAttempts++;
  120.     if (resolveAttempts > 5)
  121.     {
  122.       console.warn("Exceeded maximum name conflict resolve attempt count...");
  123.       break;
  124.     }
  125.  
  126.     conflictCount = 0;
  127.  
  128.     var conflictMap = {};
  129.     for (var i = 0; i < filesToParse.length; i++)
  130.     {
  131.       var fileInfo = filesToParse[i];
  132.       if (conflictMap[fileInfo.name] && !fileInfo.ignoreConflicts)
  133.       {
  134.         conflictCount++;
  135.         fileInfo.conflicted = true;
  136.         conflictMap[fileInfo.name].conflicted = true;
  137.       }
  138.       else
  139.       {
  140.         conflictMap[fileInfo.name] = fileInfo;
  141.       }
  142.     }
  143.  
  144.     for (var i = 0; i < filesToParse.length; i++)
  145.     {
  146.       var fileInfo = filesToParse[i];
  147.       if (fileInfo.conflicted)
  148.       {
  149.         if (fileInfo.name === fileInfo.path)
  150.         {
  151.           fileInfo.ignoreConflicts = true;
  152.         }
  153.         else
  154.         {
  155.           fileInfo.conflictResolveAttempts = (fileInfo.conflictResolveAttempts || 0) + 1;
  156.           var spl = fileInfo.path.split('/');
  157.           var newName = "";
  158.           for (var j = spl.length - (fileInfo.conflictResolveAttempts+1); j < spl.length; j++)
  159.           {
  160.             newName += spl[j];
  161.             if (j < spl.length - 1) newName += '/';
  162.           }
  163.           console.log("Resolved '" + fileInfo.name + "' into '" + newName + "'");
  164.           fileInfo.name = newName;
  165.         }
  166.         fileInfo.conflicted = null;
  167.       }
  168.     }
  169.   }
  170. }
  171.  
  172. function parseFiles()
  173. {
  174.   for (var i = 0; i < filesToParse.length; i++)
  175.   {
  176.     var fileInfo = filesToParse[i];
  177.     scanJS(fileInfo.path, fileInfo.name);
  178.   }
  179. }
  180.  
  181. function findEventName(tokenArr, startIdx)
  182. {
  183.   // Loop till we find a commo
  184.   var str = "";
  185.   for (var i = startIdx; i < tokenArr.length; i++)
  186.   {
  187.     var token = tokenArr[i];
  188.     if (token == ',' || token == ')') break;
  189.     str += token;
  190.   }
  191.   return str.trim();
  192. };
  193.  
  194. function dumpEventMap()
  195. {
  196.   var header = "";
  197.   var body = "";
  198.  
  199.   var eventCount = 0;
  200.   $.each(globalEventMap, function(key, val)
  201.   {
  202.     eventCount++;
  203.     body += (key + ":\n");
  204.     if (val.publishers)
  205.     {
  206.       body += "\tPublishers:\n";
  207.       $.each(val.publishers, function(key, val)
  208.       {
  209.         body += "\t\t";
  210.         body += key;
  211.         body += " (" + val + " locations)\n";
  212.       });
  213.     }
  214.     if (val.subscribers)
  215.     {
  216.       body += "\tSubscribers:\n";
  217.       $.each(val.subscribers, function(key, val)
  218.       {
  219.         body += "\t\t";
  220.         body += key;
  221.         body += "\n";
  222.       });
  223.     }
  224.     body += "\n";
  225.   });
  226.  
  227.   header += "== Event Map ==\n";
  228.   header += "Created on " + (new Date()).toString() + " by AnalyseEvents.js\n\n";
  229.   header += "There are " + eventCount + " documented events:\n\n";
  230.  
  231.   return header + body;
  232. }
  233.  
  234. scanDir(targetDir);
  235. resolveNameConflicts();
  236. parseFiles();
  237.  
  238. var str = dumpEventMap();
  239. if (fs.existsSync(outputFile)) fs.unlinkSync(outputFile);
  240. fs.writeFileSync(outputFile, str);
  241.  
  242. console.log("Scanned " + fileCount + " files and " + dirCount + " directories.");
  243. if (errCount > 0)
  244. {
  245.   console.log("Out of these, " + errCount + " wern't parsed due to tokeniser errors.");
  246. }
Advertisement
Add Comment
Please, Sign In to add comment