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

Add auto-import for the package.json imports field #55015

Merged
merged 34 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7c0fef4
Fix extension replacement in auto-import for `package.json#exports`
emmatown Jul 14, 2023
60ec33b
Add auto-import for package.json `imports` field
emmatown May 27, 2023
faef5fd
Fix using incorrect directory and add more tests
emmatown Aug 16, 2023
1d49909
Merge branch 'main' into auto-import-package-json-imports
emmatown Aug 16, 2023
4e676a3
Use JSON.parse
emmatown Aug 16, 2023
747e769
Merge branch 'main' into auto-import-package-json-imports
emmatown Aug 16, 2023
01ceb65
Use readJson again so they can all be replaced at the same time
emmatown Aug 17, 2023
864b9a3
Add test with conditions
emmatown Sep 11, 2023
d0407a9
Merge branch 'main' into auto-import-package-json-imports
emmatown Sep 11, 2023
e092943
Merge remote-tracking branch 'origin/main' into auto-import-package-j…
Andarist Oct 10, 2023
8f781c5
Revert "Use readJson again so they can all be replaced at the same time"
Andarist Oct 10, 2023
a2aa5ae
wrap `JSON.parse` calls with try/catch
Andarist Oct 10, 2023
eaa8e2e
Merge remote-tracking branch 'origin/main' into auto-import-package-j…
Andarist Oct 30, 2023
051239b
Add support for output file remapping
Andarist Oct 30, 2023
b3c5ca4
limit the behavior to imports
Andarist Oct 30, 2023
ea67766
add extra test case
Andarist Oct 30, 2023
7abf4a2
Merge remote-tracking branch 'origin/main' into auto-import-package-j…
Andarist Oct 30, 2023
6a72a51
fixed conflict with the recent changes on main
Andarist Oct 30, 2023
9903d72
Remove the `emitDeclarationOnly` check
Andarist Oct 30, 2023
9e2df94
Move `getCommonSourceDirectory` to the `ModuleSpecifierResolutionHost`
Andarist Oct 31, 2023
c4df857
Reuse `getCommonSourceDirectory` available in the `Program`
Andarist Oct 31, 2023
566e543
support declaration remapping
Andarist Oct 31, 2023
1f9f214
reprioritize checks
Andarist Oct 31, 2023
7a5c164
Deduplicate some emitter code
andrewbranch Nov 15, 2023
45194b2
Fix lints
andrewbranch Nov 15, 2023
8f2d0c3
Add failing test for when full path contains capital letters
andrewbranch Nov 15, 2023
8bef690
Move tryParseJson to be usable in compiler
andrewbranch Nov 15, 2023
cd84162
import `tryParseJson` after it got moved
Andarist Nov 15, 2023
8d68392
Fixed casing comparisons in `MatchingMode.Exact` and `MatchingMode.Di…
Andarist Nov 15, 2023
a9634ed
fixed the casing issue in the `MatchingMode.Pattern` case
Andarist Nov 16, 2023
7f52af2
Merge remote-tracking branch 'origin/main' into auto-import-package-j…
Andarist Nov 16, 2023
4aab191
fixed `endsWith`
Andarist Nov 16, 2023
c435528
Merge branch 'main' into auto-import-package-json-imports
andrewbranch Dec 21, 2023
4f29d3a
Fix bad merge artifacts
andrewbranch Dec 21, 2023
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
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50764,7 +50764,7 @@ export function signatureHasLiteralTypes(s: Signature) {
return !!(s.flags & SignatureFlags.HasLiteralTypes);
}

function createBasicNodeBuilderModuleSpecifierResolutionHost(host: TypeCheckerHost): ModuleSpecifierResolutionHost & { getCommonSourceDirectory(): string; } {
function createBasicNodeBuilderModuleSpecifierResolutionHost(host: TypeCheckerHost): ModuleSpecifierResolutionHost {
return {
getCommonSourceDirectory: !!(host as Program).getCommonSourceDirectory ? () => (host as Program).getCommonSourceDirectory() : () => "",
getCurrentDirectory: () => host.getCurrentDirectory(),
Expand Down
14 changes: 10 additions & 4 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2400,9 +2400,13 @@ function levenshteinWithMax(s1: string, s2: string, max: number): number | undef
}

/** @internal */
export function endsWith(str: string, suffix: string): boolean {
export function endsWith(str: string, suffix: string, ignoreCase?: boolean): boolean {
const expectedPos = str.length - suffix.length;
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
return expectedPos >= 0 && (
ignoreCase
? equateStringsCaseInsensitive(str.slice(expectedPos), suffix)
: str.indexOf(suffix, expectedPos) === expectedPos
);
}

/** @internal */
Expand Down Expand Up @@ -2579,8 +2583,10 @@ export function findBestPatternMatch<T>(values: readonly T[], getPattern: (value
}

/** @internal */
export function startsWith(str: string, prefix: string): boolean {
return str.lastIndexOf(prefix, 0) === 0;
export function startsWith(str: string, prefix: string, ignoreCase?: boolean): boolean {
return ignoreCase
? equateStringsCaseInsensitive(str.slice(0, prefix.length), prefix)
: str.lastIndexOf(prefix, 0) === 0;
}

/** @internal */
Expand Down
33 changes: 24 additions & 9 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -583,35 +583,50 @@ export function getOutputExtension(fileName: string, options: CompilerOptions):
Extension.Js;
}

function getOutputPathWithoutChangingExt(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, outputDir: string | undefined, getCommonSourceDirectory?: () => string) {
function getOutputPathWithoutChangingExt(
inputFileName: string,
ignoreCase: boolean,
outputDir: string | undefined,
getCommonSourceDirectory: () => string,
): string {
return outputDir ?
resolvePath(
outputDir,
getRelativePathFromDirectory(getCommonSourceDirectory ? getCommonSourceDirectory() : getCommonSourceDirectoryOfConfig(configFile, ignoreCase), inputFileName, ignoreCase),
getRelativePathFromDirectory(getCommonSourceDirectory(), inputFileName, ignoreCase),
) :
inputFileName;
}

/** @internal */
export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) {
export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory = () => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)) {
return getOutputDeclarationFileNameWorker(inputFileName, configFile.options, ignoreCase, getCommonSourceDirectory);
}

/** @internal */
export function getOutputDeclarationFileNameWorker(inputFileName: string, options: CompilerOptions, ignoreCase: boolean, getCommonSourceDirectory: () => string) {
return changeExtension(
getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir, getCommonSourceDirectory),
getOutputPathWithoutChangingExt(inputFileName, ignoreCase, options.declarationDir || options.outDir, getCommonSourceDirectory),
getDeclarationEmitExtensionForPath(inputFileName),
);
}

function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) {
function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory = () => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)) {
if (configFile.options.emitDeclarationOnly) return undefined;
const isJsonFile = fileExtensionIs(inputFileName, Extension.Json);
const outputFileName = changeExtension(
getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir, getCommonSourceDirectory),
getOutputExtension(inputFileName, configFile.options),
);
const outputFileName = getOutputJSFileNameWorker(inputFileName, configFile.options, ignoreCase, getCommonSourceDirectory);
return !isJsonFile || comparePaths(inputFileName, outputFileName, Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== Comparison.EqualTo ?
outputFileName :
undefined;
}

/** @internal */
export function getOutputJSFileNameWorker(inputFileName: string, options: CompilerOptions, ignoreCase: boolean, getCommonSourceDirectory: () => string): string {
return changeExtension(
getOutputPathWithoutChangingExt(inputFileName, ignoreCase, options.outDir, getCommonSourceDirectory),
getOutputExtension(inputFileName, options),
);
}

function createAddOutput() {
let outputs: string[] | undefined;
return { addOutput, getOutputs };
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,11 @@ export function isPackageJsonInfo(entry: PackageJsonInfoCacheEntry | undefined):
return !!(entry as PackageJsonInfo | undefined)?.contents;
}

/** @internal */
export function isMissingPackageJsonInfo(entry: PackageJsonInfoCacheEntry | undefined): entry is MissingPackageJsonInfo {
return !!entry && !(entry as PackageJsonInfo).contents;
}

export interface PackageJsonInfoCache {
/** @internal */ getPackageJsonInfo(packageJsonPath: string): PackageJsonInfoCacheEntry | undefined;
/** @internal */ setPackageJsonInfo(packageJsonPath: string, info: PackageJsonInfoCacheEntry): void;
Expand Down
Loading
Loading