summaryrefslogtreecommitdiff
path: root/cli/tsc
diff options
context:
space:
mode:
authorYoshiya Hinosawa <stibium121@gmail.com>2021-02-01 17:02:02 +0900
committerGitHub <noreply@github.com>2021-02-01 17:02:02 +0900
commit23281be33a378ca548f0a407f642331f20b00a43 (patch)
tree9d4d96d79e496c9e270fa91b2ed525bcdc6cdb33 /cli/tsc
parent534531e4dd4133ff22f775b385ba488ec747cead (diff)
fix(cli): fix handling of non-normalized specifier (#9357)
Diffstat (limited to 'cli/tsc')
-rw-r--r--cli/tsc/99_main_compiler.js48
1 files changed, 41 insertions, 7 deletions
diff --git a/cli/tsc/99_main_compiler.js b/cli/tsc/99_main_compiler.js
index 1dc00873d..fa25b207f 100644
--- a/cli/tsc/99_main_compiler.js
+++ b/cli/tsc/99_main_compiler.js
@@ -19,6 +19,14 @@ delete Object.prototype.__proto__;
let logDebug = false;
let logSource = "JS";
+ // The map from the normalized specifier to the original.
+ // TypeScript normalizes the specifier in its internal processing,
+ // but the original specifier is needed when looking up the source from the runtime.
+ // This map stores that relationship, and the original can be restored by the
+ // normalized specifier.
+ // See: https://github.com/denoland/deno/issues/9277#issuecomment-769653834
+ const normalizedToOriginalMap = new Map();
+
function setLogDebug(debug, source) {
logDebug = debug;
if (source) {
@@ -176,15 +184,15 @@ delete Object.prototype.__proto__;
version;
/**
* @param {string} specifier
- * @param {string} version
+ * @param {string} version
*/
constructor(specifier, version) {
this.specifier = specifier;
this.version = version;
}
/**
- * @param {number} start
- * @param {number} end
+ * @param {number} start
+ * @param {number} end
* @returns {string}
*/
getText(start, end) {
@@ -260,6 +268,9 @@ delete Object.prototype.__proto__;
return sourceFile;
}
+ // Needs the original specifier
+ specifier = normalizedToOriginalMap.get(specifier) ?? specifier;
+
/** @type {{ data: string; hash?: string; scriptKind: ts.ScriptKind }} */
const { data, hash, scriptKind } = core.jsonOpSync(
"op_load",
@@ -394,7 +405,7 @@ delete Object.prototype.__proto__;
}
/**
- * @param {{ program: ts.Program | ts.EmitAndSemanticDiagnosticsBuilderProgram, fileCount?: number }} options
+ * @param {{ program: ts.Program | ts.EmitAndSemanticDiagnosticsBuilderProgram, fileCount?: number }} options
*/
function performanceProgram({ program, fileCount }) {
if (program) {
@@ -436,6 +447,27 @@ delete Object.prototype.__proto__;
* @property {string[]} rootNames
*/
+ /**
+ * Checks the normalized version of the root name and stores it in
+ * `normalizedToOriginalMap`. If the normalized specifier is already
+ * registered for the different root name, it throws an AssertionError.
+ *
+ * @param {string} rootName
+ */
+ function checkNormalizedPath(rootName) {
+ const normalized = ts.normalizePath(rootName);
+ const originalRootName = normalizedToOriginalMap.get(normalized);
+ if (typeof originalRootName === "undefined") {
+ normalizedToOriginalMap.set(normalized, rootName);
+ } else if (originalRootName !== rootName) {
+ // The different root names are normalizd to the same path.
+ // This will cause problem when looking up the source for each.
+ throw new AssertionError(
+ `The different names for the same normalized specifier are specified: normalized=${normalized}, rootNames=${originalRootName},${rootName}`,
+ );
+ }
+ }
+
/** The API that is called by Rust when executing a request.
* @param {Request} request
*/
@@ -445,6 +477,8 @@ delete Object.prototype.__proto__;
debug(">>> exec start", { rootNames });
debug(config);
+ rootNames.forEach(checkNormalizedPath);
+
const { options, errors: configFileParsingDiagnostics } = ts
.convertCompilerOptionsFromJson(config, "");
// The `allowNonTsExtensions` is a "hidden" compiler option used in VSCode
@@ -479,15 +513,15 @@ delete Object.prototype.__proto__;
}
/**
- * @param {number} id
- * @param {any} data
+ * @param {number} id
+ * @param {any} data
*/
function respond(id, data = null) {
core.jsonOpSync("op_respond", { id, data });
}
/**
- * @param {LanguageServerRequest} request
+ * @param {LanguageServerRequest} request
*/
function serverRequest({ id, ...request }) {
debug(`serverRequest()`, { id, ...request });