UNPKG

@adpt/core

Version:
143 lines 6.05 kB
"use strict"; /* * Copyright 2018-2019 Unbounded Systems, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const path = tslib_1.__importStar(require("path")); const error_1 = require("../error"); const utils_1 = require("../utils"); const hosts_1 = require("./hosts"); const ts = tslib_1.__importStar(require("./tsmod")); const tsmod = ts.tsmod; const debugModuleResolution = false; const dtsRegex = /\.d\.ts$/; class ModuleResolver extends hosts_1.ChainableHost { constructor(compilerOptions, chainHost, id) { super((chainHost && chainHost.cwd) || "/"); this.compilerOptions = compilerOptions; if (chainHost) this.setSource(chainHost); this.cache = new Map(); if (id) this._id = id; } resolveModuleNames(moduleNames, containingFile, reusedNames) { const resolved = []; for (const modName of moduleNames) { // NOTE: ts.CompilerHost allows returning undefined for a module, but // ts.LanguageServiceHost does not. Fib a little here. resolved.push(this.resolveModuleName(modName, containingFile, false)); } return resolved; } /** * Resolve a single module name to a file path * @param modName The module name, as specified in import/require * @param containingFile The path to the file that contains the import * @param runnable Return a file that can be executed, which means either * a .js file or something that we know how to compile (ts, tsx). */ resolveModuleName(modName, containingFile, runnable) { utils_1.trace(debugModuleResolution, `Trying to resolve ${modName}`); const fn = this.realFilename(containingFile); if (!fn) throw new Error(`Unable to get real filename for ${containingFile}`); containingFile = fn; const cacheKey = `${modName}\0${containingFile}\0${runnable}`; let mod = this.cache.get(cacheKey); if (mod !== undefined) return mod === null ? undefined : mod; const r = tsmod().resolveModuleName(modName, containingFile, this.compilerOptions, this); if (r) { mod = r.resolvedModule; if (runnable) { const resolved = mod && mod.resolvedFileName; // FIXME(mark): This isn't quite the right check. It *should* // be anything we know how to run, which is .js or anything // we know how to compile. But we don't have immediate access // to which extensions we know how to compile... In practice, // rejecting .d.ts is sufficient here. if (resolved && resolved.match(dtsRegex)) { utils_1.trace(debugModuleResolution, `Initially resolved to ${resolved}, but rejecting .d.ts ` + `file because runnable=true`); mod = resolveJS(modName, containingFile, this); } } } if (mod) { utils_1.trace(debugModuleResolution, `Resolved to ${mod.resolvedFileName}`); this.cache.set(cacheKey, mod); return mod; } utils_1.trace(debugModuleResolution, `FAILED to resolve ${modName}`); this.cache.set(cacheKey, null); return undefined; } /** * Called by TS for module tracing and other debug output * @param s String to be printed to debug output stream */ trace(s) { utils_1.trace(debugModuleResolution, s); } } tslib_1.__decorate([ utils_1.tracef(debugModuleResolution), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Array, String, Array]), tslib_1.__metadata("design:returntype", void 0) ], ModuleResolver.prototype, "resolveModuleNames", null); tslib_1.__decorate([ utils_1.tracef(debugModuleResolution), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [String, String, Boolean]), tslib_1.__metadata("design:returntype", void 0) ], ModuleResolver.prototype, "resolveModuleName", null); exports.ModuleResolver = ModuleResolver; function resolveJS(modName, containingFile, host) { // The function that the TS compiler uses to resolve JS modules is // exported, but marked @internal. They also changed the name of the // function somewhere in the 3.x series. const tsResolve = tsmod().resolveJSModule || // > 3.x name tsmod().resolveJavaScriptModule; // < 3.x name if (!tsResolve) { throw new error_1.InternalError(`Unable to locate the Javascript resolver ` + `function from the TypeScript library`); } const jsFile = tsResolve(modName, path.dirname(containingFile), host); if (!jsFile) { utils_1.trace(debugModuleResolution, `JavaScript file resolution failed`); return null; } let ext; switch (path.extname(jsFile)) { case tsmod().Extension.Js: ext = tsmod().Extension.Js; break; case tsmod().Extension.Jsx: ext = tsmod().Extension.Jsx; break; default: throw new Error(`Module file extension ` + `'${path.extname(jsFile)}' not understood`); } return { resolvedFileName: jsFile, isExternalLibraryImport: true, extension: ext, }; } //# sourceMappingURL=modules.js.map