Skip to content

Commit

Permalink
fix: rollback uri.path to uri.fsPath for windows
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Sep 3, 2022
1 parent a43181a commit 2b6c3c7
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 57 deletions.
10 changes: 7 additions & 3 deletions packages/shared/src/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as upath from 'upath';
import type { DocumentUri } from 'vscode-languageserver-textdocument';

export function getPathOfUri(uri: DocumentUri) {
return URI.parse(uri).path;
return upath.toUnix(URI.parse(uri).fsPath);
}

export function normalizeFileName(fsPath: string) {
Expand All @@ -15,9 +15,13 @@ export function normalizeUri(uri: string) {
}

export function getUriByPath(rootUri: URI, path: string) {
return URI.from({
return URI.file(path).with({
scheme: rootUri.scheme,
authority: rootUri.authority,
path,
}).toString();
}

export function isFileInDir(fileName: string, dir: string) {
const relative = upath.relative(dir, fileName);
return !!relative && !relative.startsWith('..') && !upath.isAbsolute(relative);
}
2 changes: 1 addition & 1 deletion packages/vue-language-server/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function createLanguageServer(
ts,
configHost,
runtimeEnv.fileSystemProvide,
loadCustomPlugins(roots[0].path), // TODO: handle multiple roots
loadCustomPlugins(roots[0].fsPath), // TODO: handle multiple roots
roots[0],
);

Expand Down
77 changes: 39 additions & 38 deletions packages/vue-language-server/src/utils/webFileSystemHost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export function createWebFileSystemHost(

connection.onDidChangeWatchedFiles(params => {
for (const change of params.changes) {
const fileName = URI.parse(change.uri).path;
const dir = getDir(path.dirname(fileName));
const name = path.basename(fileName);
const fsPath = URI.parse(change.uri).fsPath;
const dir = getDir(path.dirname(fsPath));
const name = path.basename(fsPath);
if (change.type === vscode.FileChangeType.Created) {
dir.fileTypes.set(name, FileType.File);
}
Expand All @@ -63,7 +63,7 @@ export function createWebFileSystemHost(
return {
newLine: '\n',
useCaseSensitiveFileNames: false,
getCurrentDirectory: () => rootUri.path,
getCurrentDirectory: () => rootUri.fsPath,
fileExists,
readFile,
readDirectory,
Expand All @@ -72,52 +72,53 @@ export function createWebFileSystemHost(
realpath: path => path, // TODO: cannot implement with vscode
};

function resolvePath(fileName: string) {
if (currentCwd !== rootUri.path) {
process.chdir(rootUri.path);
currentCwd = rootUri.path;
function resolvePath(fsPath: string) {
if (currentCwd !== rootUri.fsPath) {
process.chdir(rootUri.fsPath);
currentCwd = rootUri.fsPath;
}
return path.resolve(fileName);
return path.resolve(fsPath);
}

function fileExists(fileName: string): boolean {
fileName = resolvePath(fileName);
const dir = getDir(path.dirname(fileName));
const name = path.basename(fileName);
function fileExists(fsPath: string): boolean {
fsPath = resolvePath(fsPath);
const dir = getDir(path.dirname(fsPath));
const name = path.basename(fsPath);
if (dir.fileTypes.has(name)) {
return dir.fileTypes.get(name) === FileType.File || dir.fileTypes.get(name) === FileType.SymbolicLink;
}
dir.fileTypes.set(name, undefined);
addPending(statAsync(fileName, dir));
addPending(statAsync(fsPath, dir));
return false;
}

function readFile(fileName: string) {
fileName = resolvePath(fileName);
const dir = getDir(path.dirname(fileName));
const name = path.basename(fileName);
function readFile(fsPath: string) {
fsPath = resolvePath(fsPath);
const dir = getDir(path.dirname(fsPath));
const name = path.basename(fsPath);
if (dir.fileTexts.has(name)) {
return dir.fileTexts.get(name);
}
dir.fileTexts.set(name, '');
addPending(readFileAsync(fileName, dir));
addPending(readFileAsync(fsPath, dir));
return '';
}

function readDirectory(
dirPath: string,
fsPath: string,
extensions?: readonly string[],
exclude?: readonly string[],
include?: readonly string[],
depth?: number,
) {
fsPath = resolvePath(fsPath);
return matchFiles(
dirPath,
fsPath,
extensions,
exclude,
include,
false,
rootUri.path,
rootUri.fsPath,
depth,
dirPath => {

Expand All @@ -140,33 +141,33 @@ export function createWebFileSystemHost(
}

// for import path completion
function getDirectories(dirPath: string) {
function getDirectories(fsPath: string) {

dirPath = resolvePath(dirPath);
const dir = getDir(dirPath);
fsPath = resolvePath(fsPath);

const dir = getDir(fsPath);
const files = [...dir.fileTypes];

if (!dir.searched) {
dir.searched = true;
addPending(readDirectoryAsync(dirPath, dir));
addPending(readDirectoryAsync(fsPath, dir));
}

return files.filter(file => file[1] === FileType.Directory).map(file => file[0]);
}

function getFilePathUri(path: string) {
return URI.from({
function getFsPathUri(fsPath: string) {
return URI.file(fsPath).with({
scheme: rootUri.scheme,
authority: rootUri.authority,
path: path,
});
}

async function statAsync(fileName: string, dir: Dir) {
const uri = getFilePathUri(fileName);
async function statAsync(fsPath: string, dir: Dir) {
const uri = getFsPathUri(fsPath);
const result = await connection.sendRequest(FsStatRequest.type, uri.toString());
if (result?.type === FileType.File || result?.type === FileType.SymbolicLink) {
const name = path.basename(fileName);
const name = path.basename(fsPath);
dir.fileTypes.set(name, result.type);
changes.push({
uri: uri.toString(),
Expand All @@ -175,11 +176,11 @@ export function createWebFileSystemHost(
}
}

async function readFileAsync(fileName: string, dir: Dir) {
const uri = getFilePathUri(fileName);
async function readFileAsync(fsPath: string, dir: Dir) {
const uri = getFsPathUri(fsPath);
const text = await connection.sendRequest(FsReadFileRequest.type, uri.toString());
if (text) {
const name = path.basename(fileName);
const name = path.basename(fsPath);
dir.fileTexts.set(name, text);
changes.push({
uri: uri.toString(),
Expand All @@ -188,13 +189,13 @@ export function createWebFileSystemHost(
}
}

async function readDirectoryAsync(dirPath: string, dir: Dir) {
const uri = getFilePathUri(dirPath);
async function readDirectoryAsync(fsPath: string, dir: Dir) {
const uri = getFsPathUri(fsPath);
const result = await connection.sendRequest(FsReadDirectoryRequest.type, uri.toString());
for (const [name, fileType] of result) {
if (dir.fileTypes.get(name) !== fileType && (fileType === FileType.File || fileType === FileType.SymbolicLink)) {
changes.push({
uri: getFilePathUri(path.join(dirPath, name)).toString(),
uri: getFsPathUri(path.join(fsPath, name)).toString(),
type: vscode.FileChangeType.Created,
});
}
Expand Down
26 changes: 13 additions & 13 deletions packages/vue-language-server/src/utils/workspaceProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ export async function createWorkspaceProjects(
const sys = fsHost.getWorkspaceFileSystem(rootUri);
const inferOptions = await getInferredCompilerOptions(ts, configHost);
const projects = shared.createUriAndPathMap<Project>(rootUri);
const rootTsConfigs = new Set(sys.readDirectory(rootUri.path, rootTsConfigNames, undefined, ['**/*']));
const rootTsConfigs = new Set(sys.readDirectory(rootUri.fsPath, rootTsConfigNames, undefined, ['**/*']));

const disposeWatch = fsHost.onDidChangeWatchedFiles(async (params, reason) => {
const disposes: Promise<any>[] = [];
for (const change of params.changes) {
if (rootTsConfigNames.includes(path.basename(change.uri))) {
if (change.type === vscode.FileChangeType.Created) {
if (change.uri.toLowerCase().startsWith(rootUri.toString().toLowerCase())) {
rootTsConfigs.add(URI.parse(change.uri).path);
if (shared.isFileInDir(URI.parse(change.uri).fsPath, rootUri.fsPath)) {
rootTsConfigs.add(URI.parse(change.uri).fsPath);
}
}
else if ((change.type === vscode.FileChangeType.Changed || change.type === vscode.FileChangeType.Deleted) && projects.uriHas(change.uri)) {
if (change.type === vscode.FileChangeType.Deleted) {
rootTsConfigs.delete(change.uri);
rootTsConfigs.delete(URI.parse(change.uri).fsPath);
}
const _project = projects.uriGet(change.uri);
projects.uriDelete(change.uri);
Expand Down Expand Up @@ -101,7 +101,7 @@ export async function createWorkspaceProjects(
ts,
options,
rootUri,
rootUri.path,
rootUri.fsPath,
inferOptions,
tsLocalized,
documents,
Expand All @@ -122,12 +122,12 @@ export async function createWorkspaceProjects(
let matches: string[] = [];

for (const rootTsConfig of rootTsConfigs) {
if (uri.path.toLowerCase().startsWith(path.dirname(rootTsConfig).toLowerCase())) {
if (shared.isFileInDir(uri.fsPath, path.dirname(rootTsConfig))) {
matches.push(rootTsConfig);
}
}

matches = matches.sort((a, b) => sortTsConfigs(uri.path, a, b));
matches = matches.sort((a, b) => sortTsConfigs(uri.fsPath, a, b));

if (matches.length) {
await getParsedCommandLine(matches[0]);
Expand All @@ -137,8 +137,8 @@ export async function createWorkspaceProjects(
return findTsconfig(async tsconfig => {
const parsedCommandLine = await getParsedCommandLine(tsconfig);
// use toLowerCase to fix https://github.com/johnsoncodehk/volar/issues/1125
const fileNames = new Set(parsedCommandLine.fileNames.map(fileName => fileName.toLowerCase()));
return fileNames.has(uri.path.toLowerCase());
const fileNames = new Set(parsedCommandLine.fileNames.map(fileName => shared.normalizeFileName(fileName.toLowerCase())));
return fileNames.has(shared.normalizeFileName(uri.fsPath.toLowerCase()));
});
}
function findIndirectReferenceTsconfig() {
Expand All @@ -153,7 +153,7 @@ export async function createWorkspaceProjects(

const checked = new Set<string>();

for (const rootTsConfig of [...rootTsConfigs].sort((a, b) => sortTsConfigs(uri.path, a, b))) {
for (const rootTsConfig of [...rootTsConfigs].sort((a, b) => sortTsConfigs(uri.fsPath, a, b))) {
const project = await projects.pathGet(rootTsConfig);
if (project) {

Expand Down Expand Up @@ -244,10 +244,10 @@ export async function createWorkspaceProjects(
}
}

export function sortTsConfigs(uri: string, a: string, b: string) {
export function sortTsConfigs(fsPath: string, a: string, b: string) {

const inA = uri.toLowerCase().startsWith(path.dirname(a).toLowerCase());
const inB = uri.toLowerCase().startsWith(path.dirname(b).toLowerCase());
const inA = shared.isFileInDir(fsPath, path.dirname(a));
const inB = shared.isFileInDir(fsPath, path.dirname(b));

if (inA !== inB) {
const aWeight = inA ? 1 : 0;
Expand Down
4 changes: 2 additions & 2 deletions packages/vue-language-server/src/utils/workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ export function createWorkspaces(
async function getProject(uri: string) {

const rootUris = [...workspaces.keys()]
.filter(rootUri => uri.toLowerCase().startsWith(rootUri.toLowerCase()))
.sort((a, b) => sortTsConfigs(uri, a, b));
.filter(rootUri => shared.isFileInDir(URI.parse(uri).fsPath, URI.parse(rootUri).fsPath))
.sort((a, b) => sortTsConfigs(URI.parse(uri).fsPath, URI.parse(a).fsPath, URI.parse(b).fsPath));

for (const rootUri of rootUris) {
const workspace = await workspaces.get(rootUri);
Expand Down

0 comments on commit 2b6c3c7

Please sign in to comment.