Skip to content

Commit 4257c2f

Browse files
committed
Resolve the .json file only if module name contains the extension
1 parent a790a92 commit 4257c2f

59 files changed

Lines changed: 733 additions & 92 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2084,7 +2084,7 @@ namespace ts {
20842084
}
20852085

20862086
// May be an untyped module. If so, ignore resolutionDiagnostic.
2087-
if (resolvedModule && !extensionIsTypeScript(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
2087+
if (resolvedModule && !resolutionExtensionIsTypeScriptOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
20882088
if (isForAugmentation) {
20892089
const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
20902090
error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);

src/compiler/commandLineParser.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,8 +2044,7 @@ namespace ts {
20442044

20452045
// Rather than requery this for each file and filespec, we query the supported extensions
20462046
// once and store it on the expansion context.
2047-
// When computing file names, do not include json files. Use only module resolution or explicit includes for them
2048-
const supportedExtensions = getSupportedExtensions(options, extraFileExtensions, /*excludeJson*/ true);
2047+
const supportedExtensions = getSupportedExtensions(options, extraFileExtensions);
20492048

20502049
// Literal files are always included verbatim. An "include" or "exclude" specification cannot
20512050
// remove a literal file.

src/compiler/core.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2674,21 +2674,14 @@ namespace ts {
26742674
export const supportedTypescriptExtensionsForExtractExtension: ReadonlyArray<Extension> = [Extension.Dts, Extension.Ts, Extension.Tsx];
26752675
export const supportedJavascriptExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx];
26762676
const allSupportedExtensions: ReadonlyArray<Extension> = [...supportedTypeScriptExtensions, ...supportedJavascriptExtensions];
2677-
let allSupportedExtensionsIncludingJson: ReadonlyArray<Extension> | undefined;
2678-
function getAllSupportedExtensionsIncludingJson() {
2679-
return allSupportedExtensionsIncludingJson || (allSupportedExtensionsIncludingJson = [...allSupportedExtensions, Extension.Json]);
2680-
}
26812677

2682-
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>, excludeJson?: boolean): ReadonlyArray<string> {
2678+
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>): ReadonlyArray<string> {
26832679
const needAllExtensions = options && options.allowJs;
2684-
const useJsonExtension = needAllExtensions && !excludeJson && getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeJs;
26852680
if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) {
2686-
return useJsonExtension ?
2687-
getAllSupportedExtensionsIncludingJson() :
2688-
needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions;
2681+
return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions;
26892682
}
26902683
return deduplicate(
2691-
[...(useJsonExtension ? getAllSupportedExtensionsIncludingJson() : allSupportedExtensions), ...extraFileExtensions.map(e => e.extension)],
2684+
[...allSupportedExtensions, ...extraFileExtensions.map(e => e.extension)],
26922685
equateStringsCaseSensitive,
26932686
compareStringsCaseSensitive
26942687
);
@@ -2698,10 +2691,6 @@ namespace ts {
26982691
return forEach(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension));
26992692
}
27002693

2701-
export function hasJavaScriptOrJsonFileExtension(fileName: string) {
2702-
return hasJavaScriptFileExtension(fileName) || fileExtensionIs(fileName, Extension.Json);
2703-
}
2704-
27052694
export function hasTypeScriptFileExtension(fileName: string) {
27062695
return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension));
27072696
}
@@ -3102,6 +3091,10 @@ namespace ts {
31023091
return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts;
31033092
}
31043093

3094+
export function resolutionExtensionIsTypeScriptOrJson(ext: Extension) {
3095+
return extensionIsTypeScript(ext) || ext === Extension.Json;
3096+
}
3097+
31053098
/**
31063099
* Gets the extension from a path.
31073100
* Path must have a valid extension.
@@ -3119,9 +3112,7 @@ namespace ts {
31193112
}
31203113

31213114
export function tryGetExtensionFromPath(path: string): Extension | undefined {
3122-
return find<Extension>(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) ||
3123-
find(supportedJavascriptExtensions, e => fileExtensionIs(path, e)) ||
3124-
(fileExtensionIs(path, Extension.Json) ? Extension.Json : undefined);
3115+
return find<Extension>(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || find(supportedJavascriptExtensions, e => fileExtensionIs(path, e));
31253116
}
31263117

31273118
// Retrieves any string from the final "." onwards from a base file name.

src/compiler/moduleNameResolver.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,11 @@ namespace ts {
882882
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
883883
*/
884884
function loadModuleFromFile(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
885+
if (extensions === Extensions.Json) {
886+
const extensionLess = tryRemoveExtension(candidate, Extension.Json);
887+
return extensionLess && tryAddingExtensions(extensionLess, extensions, failedLookupLocations, onlyRecordFailures, state);
888+
}
889+
885890
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
886891
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state);
887892
if (resolvedByAddingExtension) {
@@ -890,7 +895,7 @@ namespace ts {
890895

891896
// If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
892897
// e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
893-
if (hasJavaScriptOrJsonFileExtension(candidate)) {
898+
if (hasJavaScriptFileExtension(candidate)) {
894899
const extensionless = removeFileExtension(candidate);
895900
if (state.traceEnabled) {
896901
const extension = candidate.substring(extensionless.length);

src/compiler/program.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,7 +1975,7 @@ namespace ts {
19751975
}
19761976

19771977
const isFromNodeModulesSearch = resolution.isExternalLibraryImport;
1978-
const isJsFile = !extensionIsTypeScript(resolution.extension);
1978+
const isJsFile = !resolutionExtensionIsTypeScriptOrJson(resolution.extension);
19791979
const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile;
19801980
const resolvedFileName = resolution.resolvedFileName;
19811981

@@ -2405,14 +2405,14 @@ namespace ts {
24052405
switch (extension) {
24062406
case Extension.Ts:
24072407
case Extension.Dts:
2408+
case Extension.Json:
24082409
// These are always allowed.
24092410
return undefined;
24102411
case Extension.Tsx:
24112412
return needJsx();
24122413
case Extension.Jsx:
24132414
return needJsx() || needAllowJs();
24142415
case Extension.Js:
2415-
case Extension.Json:
24162416
return needAllowJs();
24172417
}
24182418

src/harness/fourslash.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,9 +511,8 @@ namespace FourSlash {
511511
}
512512

513513
private getAllDiagnostics(): ts.Diagnostic[] {
514-
const options = this.languageService.getProgram().getCompilerOptions();
515514
return ts.flatMap(this.languageServiceAdapterHost.getFilenames(), fileName =>
516-
ts.fileExtensionIsOneOf(fileName, ts.getSupportedExtensions(options)) ? this.getDiagnostics(fileName) : []);
515+
ts.isAnySupportedFileExtension(fileName) ? this.getDiagnostics(fileName) : []);
517516
}
518517

519518
public verifyErrorExistsAfterMarker(markerName: string, shouldExist: boolean, after: boolean) {

src/harness/unittests/reuseProgramStructure.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,6 @@ namespace ts {
473473
"File 'node_modules/a/index.jsx' does not exist.",
474474
"Loading module 'a' from 'node_modules' folder, target file type 'Json'.",
475475
"File 'node_modules/a/package.json' does not exist.",
476-
"File 'node_modules/a.json' does not exist.",
477-
"File 'node_modules/a/index.json' does not exist.",
478476
"======== Module name 'a' was not resolved. ========"
479477
],
480478
"initialProgram: execute module resolution normally.");

src/services/jsTyping.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ namespace ts.JsTyping {
9898
// Only infer typings for .js and .jsx files
9999
fileNames = mapDefined(fileNames, fileName => {
100100
const path = normalizePath(fileName);
101-
if (hasJavaScriptOrJsonFileExtension(path)) {
101+
if (hasJavaScriptFileExtension(path)) {
102102
return path;
103103
}
104104
});
@@ -193,7 +193,7 @@ namespace ts.JsTyping {
193193
*/
194194
function getTypingNamesFromSourceFileNames(fileNames: string[]) {
195195
const fromFileNames = mapDefined(fileNames, j => {
196-
if (!hasJavaScriptOrJsonFileExtension(j)) return undefined;
196+
if (!hasJavaScriptFileExtension(j)) return undefined;
197197

198198
const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase()));
199199
const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName);

tests/baselines/reference/jsFileCompilationWithMapFileAsJs.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error TS5055: Cannot write file 'tests/cases/compiler/b.js' because it would overwrite input file.
22
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
3-
error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'.
3+
error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.
44

55

66
!!! error TS5055: Cannot write file 'tests/cases/compiler/b.js' because it would overwrite input file.
77
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
8-
!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'.
8+
!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.
99
==== tests/cases/compiler/a.ts (0 errors) ====
1010
class c {
1111
}

tests/baselines/reference/jsFileCompilationWithMapFileAsJsWithInlineSourceMap.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error TS5055: Cannot write file 'tests/cases/compiler/b.js' because it would overwrite input file.
22
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
3-
error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'.
3+
error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.
44

55

66
!!! error TS5055: Cannot write file 'tests/cases/compiler/b.js' because it would overwrite input file.
77
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
8-
!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'.
8+
!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.
99
==== tests/cases/compiler/a.ts (0 errors) ====
1010
class c {
1111
}

0 commit comments

Comments
 (0)