Fix tsconfig resolution for navigation (#192851)

* Fix tsconfig resolution

* Resolve based on link type
This commit is contained in:
Ronak Jain 2023-11-07 01:16:09 +05:30 committed by GitHub
parent 9527021b45
commit d72005bfa7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -17,9 +17,16 @@ function mapChildren<R>(node: jsonc.Node | undefined, f: (x: jsonc.Node) => R):
} }
const openExtendsLinkCommandId = '_typescript.openExtendsLink'; const openExtendsLinkCommandId = '_typescript.openExtendsLink';
enum TsConfigLinkType {
Extends,
References
}
type OpenExtendsLinkCommandArgs = { type OpenExtendsLinkCommandArgs = {
readonly resourceUri: vscode.Uri; readonly resourceUri: vscode.Uri;
readonly extendsValue: string; readonly extendsValue: string;
readonly linkType: TsConfigLinkType;
}; };
@ -43,7 +50,7 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider {
private getExtendsLink(document: vscode.TextDocument, root: jsonc.Node): vscode.DocumentLink | undefined { private getExtendsLink(document: vscode.TextDocument, root: jsonc.Node): vscode.DocumentLink | undefined {
const node = jsonc.findNodeAtLocation(root, ['extends']); const node = jsonc.findNodeAtLocation(root, ['extends']);
return node && this.tryCreateTsConfigLink(document, node); return node && this.tryCreateTsConfigLink(document, node, TsConfigLinkType.Extends);
} }
private getReferencesLinks(document: vscode.TextDocument, root: jsonc.Node) { private getReferencesLinks(document: vscode.TextDocument, root: jsonc.Node) {
@ -51,18 +58,19 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider {
jsonc.findNodeAtLocation(root, ['references']), jsonc.findNodeAtLocation(root, ['references']),
child => { child => {
const pathNode = jsonc.findNodeAtLocation(child, ['path']); const pathNode = jsonc.findNodeAtLocation(child, ['path']);
return pathNode && this.tryCreateTsConfigLink(document, pathNode); return pathNode && this.tryCreateTsConfigLink(document, pathNode, TsConfigLinkType.References);
}); });
} }
private tryCreateTsConfigLink(document: vscode.TextDocument, node: jsonc.Node): vscode.DocumentLink | undefined { private tryCreateTsConfigLink(document: vscode.TextDocument, node: jsonc.Node, linkType: TsConfigLinkType): vscode.DocumentLink | undefined {
if (!this.isPathValue(node)) { if (!this.isPathValue(node)) {
return undefined; return undefined;
} }
const args: OpenExtendsLinkCommandArgs = { const args: OpenExtendsLinkCommandArgs = {
resourceUri: { ...document.uri.toJSON(), $mid: undefined }, resourceUri: { ...document.uri.toJSON(), $mid: undefined },
extendsValue: node.value extendsValue: node.value,
linkType
}; };
const link = new vscode.DocumentLink( const link = new vscode.DocumentLink(
@ -148,17 +156,18 @@ async function resolveNodeModulesPath(baseDirUri: vscode.Uri, pathCandidates: st
} }
} }
// Reference: https://github.com/microsoft/TypeScript/blob/febfd442cdba343771f478cf433b0892f213ad2f/src/compiler/commandLineParser.ts#L3005 // Reference Extends:https://github.com/microsoft/TypeScript/blob/febfd442cdba343771f478cf433b0892f213ad2f/src/compiler/commandLineParser.ts#L3005
// Reference Project References: https://github.com/microsoft/TypeScript/blob/7377f5cb9db19d79a6167065b323a45611c812b5/src/compiler/tsbuild.ts#L188C1-L194C2
/** /**
* @returns Returns undefined in case of lack of result while trying to resolve from node_modules * @returns Returns undefined in case of lack of result while trying to resolve from node_modules
*/ */
async function getTsconfigPath(baseDirUri: vscode.Uri, pathValue: string): Promise<vscode.Uri | undefined> { async function getTsconfigPath(baseDirUri: vscode.Uri, pathValue: string, linkType: TsConfigLinkType): Promise<vscode.Uri | undefined> {
async function resolve(absolutePath: vscode.Uri): Promise<vscode.Uri> { async function resolve(absolutePath: vscode.Uri): Promise<vscode.Uri> {
if (absolutePath.path.endsWith('.json') || await exists(absolutePath)) { if (absolutePath.path.endsWith('.json') || await exists(absolutePath)) {
return absolutePath; return absolutePath;
} }
return absolutePath.with({ return absolutePath.with({
path: `${absolutePath.path}.json` path: `${absolutePath.path}${linkType === TsConfigLinkType.References ? '/tsconfig.json' : '.json'}`
}); });
} }
@ -194,8 +203,8 @@ export function register() {
.flat(); .flat();
return vscode.Disposable.from( return vscode.Disposable.from(
vscode.commands.registerCommand(openExtendsLinkCommandId, async ({ resourceUri, extendsValue, }: OpenExtendsLinkCommandArgs) => { vscode.commands.registerCommand(openExtendsLinkCommandId, async ({ resourceUri, extendsValue, linkType }: OpenExtendsLinkCommandArgs) => {
const tsconfigPath = await getTsconfigPath(Utils.dirname(vscode.Uri.from(resourceUri)), extendsValue); const tsconfigPath = await getTsconfigPath(Utils.dirname(vscode.Uri.from(resourceUri)), extendsValue, linkType);
if (tsconfigPath === undefined) { if (tsconfigPath === undefined) {
vscode.window.showErrorMessage(vscode.l10n.t("Failed to resolve {0} as module", extendsValue)); vscode.window.showErrorMessage(vscode.l10n.t("Failed to resolve {0} as module", extendsValue));
return; return;