Skip to content
This repository has been archived by the owner on Apr 16, 2020. It is now read-only.

Commit

Permalink
irp type implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Jan 24, 2019
1 parent 8d14c12 commit c31bb8e
Show file tree
Hide file tree
Showing 11 changed files with 423 additions and 105 deletions.
11 changes: 2 additions & 9 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -864,13 +864,6 @@ E('ERR_MISSING_ARGS',
E('ERR_MISSING_DYNAMIC_INSTANTIATE_HOOK',
'The ES Module loader may not return a format of \'dynamic\' when no ' +
'dynamicInstantiate function was provided', Error);
E('ERR_MODULE_NOT_FOUND', (module, base, legacyResolution) => {
let msg = `Cannot find module '${module}' imported from ${base}.`;
if (legacyResolution)
msg += ' Legacy behavior in require() would have found it at ' +
legacyResolution;
return msg;
}, Error);
E('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times', Error);
E('ERR_NAPI_CONS_FUNCTION', 'Constructor must be a function', TypeError);
E('ERR_NAPI_INVALID_DATAVIEW_ARGS',
Expand Down Expand Up @@ -973,10 +966,10 @@ E('ERR_UNKNOWN_CREDENTIAL', '%s identifier does not exist: %s', Error);
E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s', TypeError);

// This should probably be a `TypeError`.
E('ERR_UNKNOWN_FILE_EXTENSION', 'Unknown file extension: \'%s\' imported ' +
'from %s', Error);
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s', RangeError);
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
E('ERR_UNSUPPORTED_FILE_EXTENSION', 'Unsupported file extension: \'%s\' ' +
'imported from %s', Error);

E('ERR_V8BREAKITERATOR',
'Full ICU data not installed. See https://github.com/nodejs/node/wiki/Intl',
Expand Down
56 changes: 22 additions & 34 deletions lib/internal/modules/esm/default_resolve.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,30 @@
'use strict';

const { URL } = require('url');
const CJSmodule = require('internal/modules/cjs/loader');
const internalFS = require('internal/fs/utils');
const { NativeModule } = require('internal/bootstrap/loaders');
const { extname } = require('path');
const { realpathSync } = require('fs');
const { getOptionValue } = require('internal/options');
const preserveSymlinks = getOptionValue('--preserve-symlinks');
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
const {
ERR_MODULE_NOT_FOUND,
ERR_UNKNOWN_FILE_EXTENSION
} = require('internal/errors').codes;
const { ERR_UNSUPPORTED_FILE_EXTENSION } = require('internal/errors').codes;
const { resolve: moduleWrapResolve } = internalBinding('module_wrap');
const { pathToFileURL, fileURLToPath } = require('internal/url');

const realpathCache = new Map();

function search(target, base) {
try {
return moduleWrapResolve(target, base);
} catch (e) {
e.stack; // cause V8 to generate stack before rethrow
let error = e;
try {
const questionedBase = new URL(base);
const tmpMod = new CJSmodule(questionedBase.pathname, null);
tmpMod.paths = CJSmodule._nodeModulePaths(
new URL('./', questionedBase).pathname);
const found = CJSmodule._resolveFilename(target, tmpMod);
error = new ERR_MODULE_NOT_FOUND(target, fileURLToPath(base), found);
} catch {
// ignore
}
throw error;
}
}

const extensionFormatMap = {
'__proto__': null,
'.mjs': 'esm'
'.mjs': 'esm',
'.js': 'esm'
};

const legacyExtensionFormatMap = {
'__proto__': null,
'.js': 'cjs',
'.json': 'cjs',
'.mjs': 'esm',
'.node': 'cjs'
};

function resolve(specifier, parentURL) {
Expand All @@ -51,10 +35,14 @@ function resolve(specifier, parentURL) {
};
}

let url = search(specifier,
parentURL || pathToFileURL(`${process.cwd()}/`).href);

const isMain = parentURL === undefined;
if (isMain)
parentURL = pathToFileURL(`${process.cwd()}/`).href;

const resolved = moduleWrapResolve(specifier, parentURL, isMain);

let url = resolved.url;
const legacy = resolved.legacy;

if (isMain ? !preserveSymlinksMain : !preserveSymlinks) {
const real = realpathSync(fileURLToPath(url), {
Expand All @@ -67,14 +55,14 @@ function resolve(specifier, parentURL) {
}

const ext = extname(url.pathname);
let format = (legacy ? legacyExtensionFormatMap : extensionFormatMap)[ext];

let format = extensionFormatMap[ext];
if (!format) {
if (isMain)
format = 'cjs';
format = legacy ? 'cjs' : 'esm';
else
throw new ERR_UNKNOWN_FILE_EXTENSION(url.pathname,
fileURLToPath(parentURL));
throw new ERR_UNSUPPORTED_FILE_EXTENSION(fileURLToPath(url),
fileURLToPath(parentURL));
}

return { url: `${url}`, format };
Expand Down
5 changes: 4 additions & 1 deletion lib/internal/modules/esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const ModuleJob = require('internal/modules/esm/module_job');
const defaultResolve = require('internal/modules/esm/default_resolve');
const createDynamicModule = require(
'internal/modules/esm/create_dynamic_module');
const translators = require('internal/modules/esm/translators');
const { translators } = require('internal/modules/esm/translators');

const FunctionBind = Function.call.bind(Function.prototype.bind);

Expand All @@ -32,6 +32,9 @@ class Loader {
// Registry of loaded modules, akin to `require.cache`
this.moduleMap = new ModuleMap();

// map of already-loaded CJS modules to use
this.cjsCache = new Map();

// The resolver has the signature
// (specifier : string, parentURL : string, defaultResolve)
// -> Promise<{ url : string, format: string }>
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/modules/esm/module_job.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ModuleJob {

// This is a Promise<{ module, reflect }>, whose fields will be copied
// onto `this` by `link()` below once it has been resolved.
this.modulePromise = moduleProvider(url, isMain);
this.modulePromise = moduleProvider.call(loader, url, isMain);
this.module = undefined;
this.reflect = undefined;

Expand Down
13 changes: 9 additions & 4 deletions lib/internal/modules/esm/translators.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const StringReplace = Function.call.bind(String.prototype.replace);
const debug = debuglog('esm');

const translators = new SafeMap();
module.exports = translators;
exports.translators = translators;

function initializeImportMeta(meta, { url }) {
meta.url = url;
Expand All @@ -33,7 +33,7 @@ async function importModuleDynamically(specifier, { url }) {
}

// Strategy for loading a standard JavaScript module
translators.set('esm', async (url) => {
translators.set('esm', async function(url) {
const source = `${await readFileAsync(new URL(url))}`;
debug(`Translating StandardModule ${url}`);
const module = new ModuleWrap(stripShebang(source), url);
Expand All @@ -50,9 +50,14 @@ translators.set('esm', async (url) => {
// Strategy for loading a node-style CommonJS module
const isWindows = process.platform === 'win32';
const winSepRegEx = /\//g;
translators.set('cjs', async (url, isMain) => {
translators.set('cjs', async function(url, isMain) {
debug(`Translating CJSModule ${url}`);
const pathname = internalURLModule.fileURLToPath(new URL(url));
const cached = this.cjsCache.get(url);
if (cached) {
this.cjsCache.delete(url);
return cached;
}
const module = CJSModule._cache[
isWindows ? StringReplace(pathname, winSepRegEx, '\\') : pathname];
if (module && module.loaded) {
Expand All @@ -72,7 +77,7 @@ translators.set('cjs', async (url, isMain) => {

// Strategy for loading a node builtin CommonJS module that isn't
// through normal resolution
translators.set('builtin', async (url) => {
translators.set('builtin', async function(url) {
debug(`Translating BuiltinModule ${url}`);
// slice 'node:' scheme
const id = url.slice(5);
Expand Down
4 changes: 1 addition & 3 deletions lib/internal/process/esm_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ setInitializeImportMetaObjectCallback(initializeImportMetaObject);
setImportModuleDynamicallyCallback(importModuleDynamicallyCallback);

let loaderResolve;
exports.loaderPromise = new Promise((resolve, reject) => {
loaderResolve = resolve;
});
exports.loaderPromise = new Promise((resolve) => loaderResolve = resolve);

exports.ESMLoader = undefined;

Expand Down
27 changes: 19 additions & 8 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,23 @@ namespace loader {
class ModuleWrap;

struct PackageConfig {
enum class Exists { Yes, No };
enum class IsValid { Yes, No };
enum class HasMain { Yes, No };

Exists exists;
IsValid is_valid;
HasMain has_main;
std::string main;
struct Exists {
enum Bool { No, Yes };
};
struct IsValid {
enum Bool { No, Yes };
};
struct HasMain {
enum Bool { No, Yes };
};
struct IsESM {
enum Bool { No, Yes };
};
const Exists::Bool exists;
const IsValid::Bool is_valid;
const HasMain::Bool has_main;
const std::string main;
const IsESM::Bool esm;
};
} // namespace loader

Expand Down Expand Up @@ -168,6 +177,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(env_var_settings_string, "envVarSettings") \
V(errno_string, "errno") \
V(error_string, "error") \
V(esm_string, "esm") \
V(exchange_string, "exchange") \
V(exit_code_string, "exitCode") \
V(expire_string, "expire") \
Expand Down Expand Up @@ -206,6 +216,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(kill_signal_string, "killSignal") \
V(kind_string, "kind") \
V(library_string, "library") \
V(legacy_string, "legacy") \
V(mac_string, "mac") \
V(main_string, "main") \
V(max_buffer_string, "maxBuffer") \
Expand Down
Loading

0 comments on commit c31bb8e

Please sign in to comment.