mirror of
https://github.com/denoland/deno.git
synced 2025-09-27 12:49:10 +00:00
fix(cli): fix handling of non-normalized specifier (#9357)
This commit is contained in:
parent
534531e4dd
commit
23281be33a
2 changed files with 55 additions and 7 deletions
|
@ -305,3 +305,17 @@ Deno.test({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: "Deno.emit() - non-normalized specifier and source can compile",
|
||||||
|
async fn() {
|
||||||
|
const specifier = "https://example.com/foo//bar.ts";
|
||||||
|
const { files } = await Deno.emit(specifier, {
|
||||||
|
sources: {
|
||||||
|
[specifier]: `export let foo: string = "foo";`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
assertEquals(files[`${specifier}.js`], 'export let foo = "foo";\n');
|
||||||
|
assert(typeof files[`${specifier}.js.map`] === "string");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
@ -19,6 +19,14 @@ delete Object.prototype.__proto__;
|
||||||
let logDebug = false;
|
let logDebug = false;
|
||||||
let logSource = "JS";
|
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) {
|
function setLogDebug(debug, source) {
|
||||||
logDebug = debug;
|
logDebug = debug;
|
||||||
if (source) {
|
if (source) {
|
||||||
|
@ -176,15 +184,15 @@ delete Object.prototype.__proto__;
|
||||||
version;
|
version;
|
||||||
/**
|
/**
|
||||||
* @param {string} specifier
|
* @param {string} specifier
|
||||||
* @param {string} version
|
* @param {string} version
|
||||||
*/
|
*/
|
||||||
constructor(specifier, version) {
|
constructor(specifier, version) {
|
||||||
this.specifier = specifier;
|
this.specifier = specifier;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {number} start
|
* @param {number} start
|
||||||
* @param {number} end
|
* @param {number} end
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
getText(start, end) {
|
getText(start, end) {
|
||||||
|
@ -260,6 +268,9 @@ delete Object.prototype.__proto__;
|
||||||
return sourceFile;
|
return sourceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Needs the original specifier
|
||||||
|
specifier = normalizedToOriginalMap.get(specifier) ?? specifier;
|
||||||
|
|
||||||
/** @type {{ data: string; hash?: string; scriptKind: ts.ScriptKind }} */
|
/** @type {{ data: string; hash?: string; scriptKind: ts.ScriptKind }} */
|
||||||
const { data, hash, scriptKind } = core.jsonOpSync(
|
const { data, hash, scriptKind } = core.jsonOpSync(
|
||||||
"op_load",
|
"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 }) {
|
function performanceProgram({ program, fileCount }) {
|
||||||
if (program) {
|
if (program) {
|
||||||
|
@ -436,6 +447,27 @@ delete Object.prototype.__proto__;
|
||||||
* @property {string[]} rootNames
|
* @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.
|
/** The API that is called by Rust when executing a request.
|
||||||
* @param {Request} request
|
* @param {Request} request
|
||||||
*/
|
*/
|
||||||
|
@ -445,6 +477,8 @@ delete Object.prototype.__proto__;
|
||||||
debug(">>> exec start", { rootNames });
|
debug(">>> exec start", { rootNames });
|
||||||
debug(config);
|
debug(config);
|
||||||
|
|
||||||
|
rootNames.forEach(checkNormalizedPath);
|
||||||
|
|
||||||
const { options, errors: configFileParsingDiagnostics } = ts
|
const { options, errors: configFileParsingDiagnostics } = ts
|
||||||
.convertCompilerOptionsFromJson(config, "");
|
.convertCompilerOptionsFromJson(config, "");
|
||||||
// The `allowNonTsExtensions` is a "hidden" compiler option used in VSCode
|
// The `allowNonTsExtensions` is a "hidden" compiler option used in VSCode
|
||||||
|
@ -479,15 +513,15 @@ delete Object.prototype.__proto__;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} id
|
* @param {number} id
|
||||||
* @param {any} data
|
* @param {any} data
|
||||||
*/
|
*/
|
||||||
function respond(id, data = null) {
|
function respond(id, data = null) {
|
||||||
core.jsonOpSync("op_respond", { id, data });
|
core.jsonOpSync("op_respond", { id, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {LanguageServerRequest} request
|
* @param {LanguageServerRequest} request
|
||||||
*/
|
*/
|
||||||
function serverRequest({ id, ...request }) {
|
function serverRequest({ id, ...request }) {
|
||||||
debug(`serverRequest()`, { id, ...request });
|
debug(`serverRequest()`, { id, ...request });
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue