/plugins/c9.ide.language.jsonalyzer/worker/handlers/jsonalyzer_js.js

https://gitlab.com/unofficial-mirrors/c9-core · JavaScript · 106 lines · 80 code · 18 blank · 8 comment · 14 complexity · 10664e8c808ba0c1eb4e08bff183f72a MD5 · raw file

  1. /**
  2. * jsonalyzer basic JavaScript analysis
  3. *
  4. * @copyright 2013, Ajax.org B.V.
  5. * @author Lennart Kats <lennart add c9.io>
  6. */
  7. define(function(require, exports, module) {
  8. var jsonalyzer = require("plugins/c9.ide.language.jsonalyzer/worker/jsonalyzer_worker");
  9. var PluginBase = require("plugins/c9.ide.language.jsonalyzer/worker/jsonalyzer_base_handler");
  10. var ctagsUtil = require("plugins/c9.ide.language.jsonalyzer/worker/ctags/ctags_util");
  11. var pathUtil = require("plugins/c9.ide.language.javascript.infer/path");
  12. var TAGS = [
  13. {
  14. regex: /function\s*([A-Za-z0-9$_]+)\s*\(/g,
  15. kind: "unknown2"
  16. },
  17. {
  18. regex: /exports\.([A-Za-z0-9$_]+)\s*=\s*function\b/g,
  19. kind: "unknown2"
  20. },
  21. {
  22. // HACK: architect documentation contribution
  23. regex: /\s(\w+)\s*:\s*\w+(?:\s|,)/g,
  24. kind: "unknown2",
  25. docOnly: true
  26. }
  27. ];
  28. var GUESS_FARGS = true;
  29. var EXTRACT_DOCS = true;
  30. var handler = module.exports = Object.create(PluginBase);
  31. handler.extensions = ["js", "jsx"];
  32. handler.languages = ["javascript", "jsx"];
  33. handler.analyzeCurrent = function(path, doc, ast, options, callback) {
  34. if (doc === "")
  35. return callback(null, {});
  36. if (doc.length > jsonalyzer.getMaxFileSizeSupported())
  37. return callback(null, {});
  38. var results = {};
  39. TAGS.forEach(function(tag) {
  40. if (tag.kind === "import")
  41. return;
  42. ctagsUtil.findMatchingTags(path, doc, tag, EXTRACT_DOCS, GUESS_FARGS, results);
  43. });
  44. for (var p in results) {
  45. if (results[p][0])
  46. results[p][0].kind = null;
  47. }
  48. callback(null, { properties: results });
  49. };
  50. handler.analyzeOthers = handler.analyzeCurrentAll;
  51. handler.findImports = function(path, doc, ast, options, callback) {
  52. var openFiles = ctagsUtil.findMatchingOpenFiles(path);
  53. var astImports = findImportsInAST(path, ast);
  54. callback(null, openFiles.concat(astImports));
  55. };
  56. function findImportsInAST(path, ast) {
  57. if (!ast)
  58. return [];
  59. return []; // Don't import anything now that tern does this for us
  60. var basePath = path.match(/^(.*?)(\/[^\/]+)?$/)[1];
  61. return ast.collectTopDown(
  62. 'Call(Var("require"), [String(required)])', function(b) {
  63. var name = b.required.value;
  64. if (name.match(/^text!/))
  65. return;
  66. var isFilePath = pathUtil.isAbsolutePath(name) || pathUtil.isRelativePath(name);
  67. // HACK: we only support file paths right now
  68. if (!isFilePath)
  69. name = guessFilePath(basePath, name);
  70. if (!name)
  71. return;
  72. var result = isFilePath ? pathUtil.canonicalizePath(name, basePath) : "js_p:" + name;
  73. if (isFilePath && !result.match(/\.js$/))
  74. result += ".js";
  75. return result;
  76. }
  77. ).toArray();
  78. }
  79. function guessFilePath(basePath, importPath) {
  80. var baseDir = importPath.match(/[^\/]+/);
  81. if (!baseDir)
  82. return;
  83. var i = basePath.indexOf(baseDir[0]);
  84. if (i === -1)
  85. return;
  86. return basePath.substr(0, i) + importPath;
  87. }
  88. });