relative.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. var assert = require("assert");
  2. var Q = require("q");
  3. var path = require("path");
  4. var util = require("./util");
  5. var recast = require("recast");
  6. var n = recast.types.namedTypes;
  7. function Relativizer(reader) {
  8. assert.ok(this instanceof Relativizer);
  9. assert.ok(reader === null ||
  10. reader instanceof require("./reader").ModuleReader);
  11. Object.defineProperties(this, {
  12. reader: { value: reader }
  13. });
  14. }
  15. var Rp = Relativizer.prototype;
  16. exports.getProcessor = function(reader) {
  17. var relativizer = new Relativizer(reader);
  18. return function(id, input) {
  19. return relativizer.processSourceP(id, input);
  20. };
  21. };
  22. Rp.processSourceP = function(id, input) {
  23. var relativizer = this;
  24. var output = typeof input === "string" ? {
  25. ".js": input
  26. } : input;
  27. return Q(output[".js"]).then(function(source) {
  28. var promises = [];
  29. var ast = recast.parse(source);
  30. function fixRequireP(literal) {
  31. promises.push(relativizer.relativizeP(
  32. id, literal.value
  33. ).then(function(newValue) {
  34. return literal.value = newValue;
  35. }));
  36. }
  37. recast.visit(ast, {
  38. visitCallExpression: function(path) {
  39. var args = path.value.arguments;
  40. var callee = path.value.callee;
  41. if (n.Identifier.check(callee) &&
  42. callee.name === "require" &&
  43. args.length === 1) {
  44. var arg = args[0];
  45. if (n.Literal.check(arg) &&
  46. typeof arg.value === "string") {
  47. fixRequireP(arg);
  48. }
  49. }
  50. this.traverse(path);
  51. }
  52. });
  53. return Q.all(promises).then(function() {
  54. output[".js"] = recast.print(ast).code;
  55. return output;
  56. });
  57. });
  58. };
  59. Rp.absolutizeP = function(moduleId, requiredId) {
  60. requiredId = util.absolutize(moduleId, requiredId);
  61. if (this.reader)
  62. return this.reader.getCanonicalIdP(requiredId);
  63. return Q(requiredId);
  64. };
  65. Rp.relativizeP = function(moduleId, requiredId) {
  66. return this.absolutizeP(
  67. moduleId,
  68. requiredId
  69. ).then(function(absoluteId) {
  70. return util.relativize(moduleId, absoluteId);
  71. });
  72. };