author | André Bargull <andre.bargull@gmail.com> |
Thu, 02 Mar 2017 02:35:15 -0800 | |
changeset 345600 | 2cd83ad751203f5f91b1a1411fb930be9bff18c1 |
parent 345599 | 9b990c5890a81b46e4ffd8ae28c230effe9fba40 |
child 345601 | 08df0e07f0ba02a27e532b25a0d3415166a6bba1 |
push id | 87617 |
push user | cbook@mozilla.com |
push date | Thu, 02 Mar 2017 15:32:29 +0000 |
treeherder | mozilla-inbound@08df0e07f0ba [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jonco |
bugs | 1342478 |
milestone | 54.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/shell/ModuleLoader.js +++ b/js/src/shell/ModuleLoader.js @@ -9,29 +9,59 @@ // Save standard built-ins before scripts can modify them. const ArrayPrototypeJoin = Array.prototype.join; const MapPrototypeGet = Map.prototype.get; const MapPrototypeHas = Map.prototype.has; const MapPrototypeSet = Map.prototype.set; const ObjectDefineProperty = Object.defineProperty; const ReflectApply = Reflect.apply; const StringPrototypeIndexOf = String.prototype.indexOf; +const StringPrototypeLastIndexOf = String.prototype.lastIndexOf; +const StringPrototypeStartsWith = String.prototype.startsWith; const StringPrototypeSubstring = String.prototype.substring; const ReflectLoader = new class { constructor() { this.registry = new Map(); + this.modulePaths = new Map(); this.loadPath = getModuleLoadPath(); } - resolve(name) { + resolve(name, module) { if (os.path.isAbsolute(name)) return name; - return os.path.join(this.loadPath, name); + let loadPath = this.loadPath; + if (module) { + // Treat |name| as a relative path if it starts with either "./" + // or "../". + let isRelative = ReflectApply(StringPrototypeStartsWith, name, ["./"]) + || ReflectApply(StringPrototypeStartsWith, name, ["../"]) +#ifdef XP_WIN + || ReflectApply(StringPrototypeStartsWith, name, [".\\"]) + || ReflectApply(StringPrototypeStartsWith, name, ["..\\"]) +#endif + ; + + // If |name| is a relative path and |module|'s path is available, + // load |name| relative to the referring module. + if (isRelative && ReflectApply(MapPrototypeHas, this.modulePaths, [module])) { + let modulePath = ReflectApply(MapPrototypeGet, this.modulePaths, [module]); + let sepIndex = ReflectApply(StringPrototypeLastIndexOf, modulePath, ["/"]); +#ifdef XP_WIN + let otherSepIndex = ReflectApply(StringPrototypeLastIndexOf, modulePath, ["\\"]); + if (otherSepIndex > sepIndex) + sepIndex = otherSepIndex; +#endif + if (sepIndex >= 0) + loadPath = ReflectApply(StringPrototypeSubstring, modulePath, [0, sepIndex]); + } + } + + return os.path.join(loadPath, name); } normalize(path) { #ifdef XP_WIN // Replace all forward slashes with backward slashes. // NB: It may be tempting to replace this loop with a call to // String.prototype.replace, but user scripts may have modified // String.prototype or RegExp.prototype built-in functions, which makes @@ -119,34 +149,35 @@ const ReflectLoader = new class { loadAndParse(path) { let normalized = this.normalize(path); if (ReflectApply(MapPrototypeHas, this.registry, [normalized])) return ReflectApply(MapPrototypeGet, this.registry, [normalized]); let source = this.fetch(path); let module = parseModule(source, path); ReflectApply(MapPrototypeSet, this.registry, [normalized, module]); + ReflectApply(MapPrototypeSet, this.modulePaths, [module, path]); return module; } loadAndExecute(path) { let module = this.loadAndParse(path); module.declarationInstantiation(); return module.evaluation(); } importRoot(path) { return this.loadAndExecute(path); } ["import"](name, referrer) { - let path = this.resolve(name); + let path = this.resolve(name, null); return this.loadAndExecute(path); } }; setModuleResolveHook((module, requestName) => { - let path = ReflectLoader.resolve(requestName); + let path = ReflectLoader.resolve(requestName, module); return ReflectLoader.loadAndParse(path) }); Reflect.Loader = ReflectLoader; }