Allow clickable links to absolute tsconfig extends paths (#182921)

Fixes #182898
This commit is contained in:
Matt Bierner
2023-05-18 16:05:34 -07:00
committed by GitHub
parent 5015de8fb2
commit 65123b465a
3 changed files with 20 additions and 19 deletions

View File

@@ -8,7 +8,7 @@ import { basename, posix } from 'path';
import * as vscode from 'vscode';
import { Utils } from 'vscode-uri';
import { coalesce } from '../utils/arrays';
import { exists } from '../utils/fs';
import { exists, looksLikeAbsoluteWindowsPath } from '../utils/fs';
function mapChildren<R>(node: jsonc.Node | undefined, f: (x: jsonc.Node) => R): R[] {
return node && node.type === 'array' && node.children
@@ -48,10 +48,6 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider {
}
const extendsValue: string = extendsNode.value;
if (extendsValue.startsWith('/')) {
return undefined;
}
const args: OpenExtendsLinkCommandArgs = {
resourceUri: { ...document.uri.toJSON(), $mid: undefined }, // Prevent VS Code from trying to transform the uri
extendsValue: extendsValue
@@ -161,13 +157,8 @@ async function resolveNodeModulesPath(baseDirUri: vscode.Uri, pathCandidates: st
* @returns Returns undefined in case of lack of result while trying to resolve from node_modules
*/
async function getTsconfigPath(baseDirUri: vscode.Uri, extendsValue: string): Promise<vscode.Uri | undefined> {
// Don't take into account a case, where tsconfig might be resolved from the root (see the reference)
// e.g. C:/projects/shared-tsconfig/tsconfig.json (note that C: prefix is optional)
const isRelativePath = ['./', '../'].some(str => extendsValue.startsWith(str));
if (isRelativePath) {
const absolutePath = vscode.Uri.joinPath(baseDirUri, extendsValue);
if (await exists(absolutePath) || absolutePath.path.endsWith('.json')) {
async function resolve(absolutePath: vscode.Uri): Promise<vscode.Uri> {
if (absolutePath.path.endsWith('.json') || await exists(absolutePath)) {
return absolutePath;
}
return absolutePath.with({
@@ -175,6 +166,15 @@ async function getTsconfigPath(baseDirUri: vscode.Uri, extendsValue: string): Pr
});
}
const isRelativePath = ['./', '../'].some(str => extendsValue.startsWith(str));
if (isRelativePath) {
return resolve(vscode.Uri.joinPath(baseDirUri, extendsValue));
}
if (extendsValue.startsWith('/') || looksLikeAbsoluteWindowsPath(extendsValue)) {
return resolve(vscode.Uri.file(extendsValue));
}
// Otherwise resolve like a module
return resolveNodeModulesPath(baseDirUri, [
extendsValue,

View File

@@ -5,7 +5,7 @@
import * as vscode from 'vscode';
export const exists = async (resource: vscode.Uri): Promise<boolean> => {
export async function exists(resource: vscode.Uri): Promise<boolean> {
try {
const stat = await vscode.workspace.fs.stat(resource);
// stat.type is an enum flag
@@ -13,4 +13,8 @@ export const exists = async (resource: vscode.Uri): Promise<boolean> => {
} catch {
return false;
}
};
}
export function looksLikeAbsoluteWindowsPath(path: string): boolean {
return /^[a-zA-Z]:[\/\\]/.test(path);
}

View File

@@ -5,6 +5,7 @@
import * as vscode from 'vscode';
import * as fileSchemes from '../configuration/fileSchemes';
import { looksLikeAbsoluteWindowsPath } from './fs';
/**
* Maps of file resources
@@ -89,13 +90,9 @@ export class ResourceMap<T> {
}
private isCaseInsensitivePath(path: string) {
if (isWindowsPath(path)) {
if (looksLikeAbsoluteWindowsPath(path)) {
return true;
}
return path[0] === '/' && this.config.onCaseInsensitiveFileSystem;
}
}
function isWindowsPath(path: string): boolean {
return /^[a-zA-Z]:[\/\\]/.test(path);
}