Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow export map entries to remap back to input files for a program #47925

Merged
merged 7 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,15 @@
"code": 2207
},

"The project root is ambiguous, but is required to resolve export map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": {
"category": "Error",
"code": 2209
},
"The project root is ambiguous, but is required to resolve import map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": {
"category": "Error",
"code": 2210
},

"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2300
Expand Down
182 changes: 169 additions & 13 deletions src/compiler/moduleNameResolver.ts

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,36 @@ namespace ts {

return program;

function addResolutionDiagnostics(list: Diagnostic[] | undefined) {
if (!list) return;
for (const elem of list) {
programDiagnostics.add(elem);
}
}

function pullDiagnosticsFromCache(names: string[] | readonly FileReference[], containingFile: SourceFile) {
if (!moduleResolutionCache) return;
const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory);
const containingFileMode = !isString(containingFile) ? containingFile.impliedNodeFormat : undefined;
const containingDir = getDirectoryPath(containingFileName);
const redirectedReference = getRedirectReferenceForResolution(containingFile);
let i = 0;
for (const n of names) {
// mimics logic done in the resolution cache, should be resilient to upgrading it to use `FileReference`s for non-type-reference modal lookups to make it rely on the index in the list less
const mode = typeof n === "string" ? getModeForResolutionAtIndex(containingFile, i) : getModeForFileReference(n, containingFileMode);
const name = typeof n === "string" ? n : n.fileName;
i++;
// only nonrelative names hit the cache, and, at least as of right now, only nonrelative names can issue diagnostics
// (Since diagnostics are only issued via import or export map lookup)
// This may totally change if/when the issue of output paths not mapping to input files is fixed in a broader context
// When it is, how we extract diagnostics from the module name resolver will have the be refined - the current cache
// APIs wrapping the underlying resolver make it almost impossible to smuggle the diagnostics out in a generalized way
if (isExternalModuleNameRelative(name)) continue;
const diags = moduleResolutionCache.getOrCreateCacheForModuleName(name, mode, redirectedReference).get(containingDir)?.resolutionDiagnostics;
addResolutionDiagnostics(diags);
}
}

function resolveModuleNamesWorker(moduleNames: string[], containingFile: SourceFile, reusedNames: string[] | undefined): readonly ResolvedModuleFull[] {
if (!moduleNames.length) return emptyArray;
const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory);
Expand All @@ -1374,6 +1404,7 @@ namespace ts {
performance.mark("afterResolveModule");
performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule");
tracing?.pop();
pullDiagnosticsFromCache(moduleNames, containingFile);
return result;
}

Expand Down
4 changes: 4 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6717,6 +6717,8 @@ namespace ts {
readonly resolvedModule: ResolvedModuleFull | undefined;
/* @internal */
readonly failedLookupLocations: string[];
/* @internal */
readonly resolutionDiagnostics: Diagnostic[]
}

export interface ResolvedTypeReferenceDirective {
Expand All @@ -6738,6 +6740,8 @@ namespace ts {
export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
readonly resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined;
readonly failedLookupLocations: string[];
/* @internal */
resolutionDiagnostics: Diagnostic[]
}

/* @internal */
Expand Down
10 changes: 10 additions & 0 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4387,6 +4387,16 @@ namespace ts {
Extension.Dts;
}

/**
* This function is an inverse of `getDeclarationEmitExtensionForPath`.
*/
export function getPossibleOriginalInputExtensionForExtension(path: string) {
return fileExtensionIsOneOf(path, [Extension.Dmts, Extension.Mjs, Extension.Mts]) ? [Extension.Mts, Extension.Mjs] :
fileExtensionIsOneOf(path, [Extension.Dcts, Extension.Cjs, Extension.Cts]) ? [Extension.Cts, Extension.Cjs]:
fileExtensionIsOneOf(path, [`.json.d.ts`]) ? [Extension.Json] :
[Extension.Tsx, Extension.Ts, Extension.Jsx, Extension.Js];
}

export function outFile(options: CompilerOptions) {
return options.outFile || options.out;
}
Expand Down
6 changes: 6 additions & 0 deletions src/testRunner/unittests/moduleResolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ namespace ts {
extension: Extension.Ts,
},
failedLookupLocations: [],
resolutionDiagnostics: [],
});
assert.isDefined(cache.get("/sub"));
assert.isUndefined(cache.get("/"));
Expand All @@ -228,6 +229,7 @@ namespace ts {
extension: Extension.Ts,
},
failedLookupLocations: [],
resolutionDiagnostics: [],
});
assert.isDefined(cache.get("/sub/dir/foo"));
assert.isDefined(cache.get("/sub/dir"));
Expand All @@ -243,6 +245,7 @@ namespace ts {
extension: Extension.Ts,
},
failedLookupLocations: [],
resolutionDiagnostics: [],
});
assert.isDefined(cache.get("/foo/bar"));
assert.isDefined(cache.get("/foo"));
Expand All @@ -257,6 +260,7 @@ namespace ts {
extension: Extension.Ts,
},
failedLookupLocations: [],
resolutionDiagnostics: [],
});
assert.isDefined(cache.get("/foo"));
assert.isUndefined(cache.get("/"));
Expand All @@ -270,6 +274,7 @@ namespace ts {
extension: Extension.Ts,
},
failedLookupLocations: [],
resolutionDiagnostics: [],
});
assert.isDefined(cache.get("c:/foo"));
assert.isDefined(cache.get("c:/"));
Expand All @@ -279,6 +284,7 @@ namespace ts {
cache.set("/foo/bar/baz", {
resolvedModule: undefined,
failedLookupLocations: [],
resolutionDiagnostics: [],
});
assert.isDefined(cache.get("/foo/bar/baz"));
assert.isDefined(cache.get("/foo/bar"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/allowJs/index.cjs(2,23): error TS1471: Module 'package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.


!!! error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/allowJs/index.js (0 errors) ====
// esm format file
import * as self from "package";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/allowJs/index.cjs(2,23): error TS1471: Module 'package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.


!!! error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/allowJs/index.js (0 errors) ====
// esm format file
import * as self from "package";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/allowJs/index.cjs(3,22): error TS1471: Module 'package/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/index.cjs(4,23): error TS1471: Module 'package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/node_modules/inner/index.d.mts(2,13): error TS2303: Circular definition of import alias 'cjs'.
tests/cases/conformance/node/allowJs/node_modules/inner/index.d.ts(2,13): error TS2303: Circular definition of import alias 'cjs'.


!!! error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/allowJs/index.js (0 errors) ====
// esm format file
import * as cjs from "package/cjs";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/allowJs/index.cjs(3,22): error TS1471: Module 'package/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/index.cjs(4,23): error TS1471: Module 'package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/node_modules/inner/index.d.mts(2,13): error TS2303: Circular definition of import alias 'cjs'.
tests/cases/conformance/node/allowJs/node_modules/inner/index.d.ts(2,13): error TS2303: Circular definition of import alias 'cjs'.


!!! error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/allowJs/index.js (0 errors) ====
// esm format file
import * as cjs from "package/cjs";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/allowJs/index.cjs(3,22): error TS1471: Module 'package/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/index.cjs(4,23): error TS1471: Module 'package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/index.cjs(9,23): error TS1471: Module 'inner/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
Expand All @@ -6,6 +7,7 @@ tests/cases/conformance/node/allowJs/node_modules/inner/index.d.ts(2,13): error
tests/cases/conformance/node/allowJs/node_modules/inner/index.d.ts(3,22): error TS1471: Module 'inner/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.


!!! error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/allowJs/index.js (0 errors) ====
// esm format file
import * as cjs from "package/cjs";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/allowJs/index.cjs(3,22): error TS1471: Module 'package/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/index.cjs(4,23): error TS1471: Module 'package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/index.cjs(9,23): error TS1471: Module 'inner/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
Expand All @@ -6,6 +7,7 @@ tests/cases/conformance/node/allowJs/node_modules/inner/index.d.ts(2,13): error
tests/cases/conformance/node/allowJs/node_modules/inner/index.d.ts(3,22): error TS1471: Module 'inner/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.


!!! error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/allowJs/index.js (0 errors) ====
// esm format file
import * as cjs from "package/cjs";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
error TS2210: The project root is ambiguous, but is required to resolve import map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/allowJs/index.cjs(3,22): error TS1471: Module '#mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/index.cjs(4,23): error TS1471: Module '#type' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.


!!! error TS2210: The project root is ambiguous, but is required to resolve import map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/allowJs/index.js (0 errors) ====
// esm format file
import * as cjs from "#cjs";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
error TS2210: The project root is ambiguous, but is required to resolve import map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/allowJs/index.cjs(3,22): error TS1471: Module '#mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/allowJs/index.cjs(4,23): error TS1471: Module '#type' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.


!!! error TS2210: The project root is ambiguous, but is required to resolve import map entry '.' in file 'tests/cases/conformance/node/allowJs/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/allowJs/index.js (0 errors) ====
// esm format file
import * as cjs from "#cjs";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/index.cts(3,22): error TS1471: Module 'package/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/index.cts(4,23): error TS1471: Module 'package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/node_modules/inner/index.d.mts(2,13): error TS2303: Circular definition of import alias 'cjs'.
tests/cases/conformance/node/node_modules/inner/index.d.ts(2,13): error TS2303: Circular definition of import alias 'cjs'.


!!! error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/index.ts (0 errors) ====
// esm format file
import * as cjs from "package/cjs";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/package.json'. Supply the `rootDir` compiler option to disambiguate.
tests/cases/conformance/node/index.cts(3,22): error TS1471: Module 'package/mjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/index.cts(4,23): error TS1471: Module 'package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
tests/cases/conformance/node/node_modules/inner/index.d.mts(2,13): error TS2303: Circular definition of import alias 'cjs'.
tests/cases/conformance/node/node_modules/inner/index.d.ts(2,13): error TS2303: Circular definition of import alias 'cjs'.


!!! error TS2209: The project root is ambiguous, but is required to resolve export map entry '.' in file 'tests/cases/conformance/node/package.json'. Supply the `rootDir` compiler option to disambiguate.
==== tests/cases/conformance/node/index.ts (0 errors) ====
// esm format file
import * as cjs from "package/cjs";
Expand Down
Loading