Skip to content

Commit

Permalink
fix(typescript): sys cache is not updated correctly in case sensitive…
Browse files Browse the repository at this point in the history
… FS (#153)
  • Loading branch information
johnsoncodehk committed Mar 21, 2024
1 parent b419529 commit 17d1fa2
Showing 1 changed file with 55 additions and 21 deletions.
76 changes: 55 additions & 21 deletions packages/typescript/lib/protocol/createSys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import * as path from 'path-browserify';
import { matchFiles } from '../typescript/utilities';

interface File {
name: string;
text?: string;
stat?: FileStat;
requestedText?: boolean;
requestedStat?: boolean;
requestedText: boolean;
requestedStat: boolean;
}

interface Dir {
name: string;
dirs: Map<string, Dir>;
files: Map<string, File>;
exists?: boolean;
Expand All @@ -27,11 +29,13 @@ export function createSys(
version: number;
sync(): Promise<number>;
} & Disposable {

let version = 0;

// sys is undefined in browser
const sys = ts.sys as ts.System | undefined;
const caseSensitive = sys?.useCaseSensitiveFileNames ?? false;
const root: Dir = {
name: '',
dirs: new Map(),
files: new Map(),
requestedRead: false,
Expand All @@ -46,18 +50,21 @@ export function createSys(
if (dir.files.has(baseName) || dir.requestedRead) { // is requested file or directory
version++;
if (change.type === 1 satisfies typeof FileChangeType.Created || change.type === 2 satisfies typeof FileChangeType.Changed) {
dir.files.set(baseName, {
dir.files.set(normalizeFileId(baseName), {
name: baseName,
stat: {
type: 1 satisfies FileType.File,
ctime: Date.now(),
mtime: Date.now(),
size: -1,
},
requestedStat: false,
requestedText: false,
});
}
else if (change.type === 3 satisfies typeof FileChangeType.Deleted) {
dir.files.set(baseName, {
dir.files.set(normalizeFileId(baseName), {
name: baseName,
stat: undefined,
text: undefined,
requestedStat: true,
Expand All @@ -74,7 +81,7 @@ export function createSys(
},
args: sys?.args ?? [],
newLine: sys?.newLine ?? '\n',
useCaseSensitiveFileNames: sys?.useCaseSensitiveFileNames ?? false,
useCaseSensitiveFileNames: caseSensitive,
realpath: sys?.realpath,
write: sys?.write ?? (() => { }),
writeFile: sys?.writeFile ?? (() => { }),
Expand Down Expand Up @@ -127,7 +134,7 @@ export function createSys(
const name = path.basename(fileName);

readFileWorker(fileName, encoding, dir);
return dir.files.get(name)?.text;
return dir.files.get(normalizeFileId(name))?.text;
}

function directoryExists(dirName: string): boolean {
Expand Down Expand Up @@ -205,9 +212,13 @@ export function createSys(
const dirPath = path.dirname(fileName);
const baseName = path.basename(fileName);
const dir = getDir(dirPath);
let file = dir.files.get(baseName);
let file = dir.files.get(normalizeFileId(baseName));
if (!file) {
dir.files.set(baseName, file = {});
dir.files.set(normalizeFileId(baseName), file = {
name: baseName,
requestedStat: false,
requestedText: false,
});
}

return file;
Expand All @@ -218,7 +229,9 @@ export function createSys(
dirName = resolvePath(dirName);
readDirectoryWorker(dirName);
const dir = getDir(dirName);
return [...dir.dirs.entries()].filter(([_, dir]) => dir.exists).map(([name]) => name);
return [...dir.dirs.values()]
.filter(dir => dir.exists)
.map(dir => dir.name);
}

function readDirectory(
Expand All @@ -234,7 +247,7 @@ export function createSys(
extensions,
excludes,
includes,
sys?.useCaseSensitiveFileNames ?? false,
caseSensitive,
currentDirectory,
depth,
dirPath => {
Expand All @@ -244,8 +257,12 @@ export function createSys(
const dir = getDir(dirPath);

return {
files: [...dir.files.entries()].filter(([_, file]) => file.stat?.type === 1 satisfies FileType.File).map(([name]) => name),
directories: [...dir.dirs.entries()].filter(([_, dir]) => dir.exists).map(([name]) => name),
files: [...dir.files.values()]
.filter(file => file.stat?.type === 1 satisfies FileType.File)
.map(file => file.name),
directories: [...dir.dirs.values()]
.filter(dir => dir.exists)
.map(dir => dir.name),
};
},
sys?.realpath ? (path => sys.realpath!(path)) : (path => path),
Expand All @@ -257,9 +274,13 @@ export function createSys(

const name = path.basename(fileName);

let file = dir.files.get(name);
let file = dir.files.get(normalizeFileId(name));
if (!file) {
dir.files.set(name, file = {});
dir.files.set(normalizeFileId(name), file = {
name,
requestedStat: false,
requestedText: false,
});
}

if (file.requestedText) {
Expand Down Expand Up @@ -330,9 +351,13 @@ export function createSys(
stat.then(stat => {
promises.delete(promise);
if (stat?.type === 1 satisfies FileType.File) {
let file = dir.files.get(name);
let file = dir.files.get(normalizeFileId(name));
if (!file) {
dir.files.set(name, file = {});
dir.files.set(normalizeFileId(name), file = {
name,
requestedStat: false,
requestedText: false,
});
}
if (stat.type !== file.stat?.type || stat.mtime !== file.stat?.mtime) {
version++;
Expand All @@ -354,9 +379,13 @@ export function createSys(
}
}
if (fileType === 1 satisfies FileType.File) {
let file = dir.files.get(name);
let file = dir.files.get(normalizeFileId(name));
if (!file) {
dir.files.set(name, file = {});
dir.files.set(normalizeFileId(name), file = {
name,
requestedStat: false,
requestedText: false,
});
}
if (!file.stat) {
file.stat = {
Expand Down Expand Up @@ -405,13 +434,18 @@ export function createSys(
}

function getDirFromDir(dir: Dir, name: string) {
let target = dir.dirs.get(name);
let target = dir.dirs.get(normalizeFileId(name));
if (!target) {
dir.dirs.set(name, target = {
dir.dirs.set(normalizeFileId(name), target = {
name,
dirs: new Map(),
files: new Map(),
});
}
return target;
}

function normalizeFileId(fileName: string) {
return caseSensitive ? fileName : fileName.toLowerCase();
}
}

0 comments on commit 17d1fa2

Please sign in to comment.