file watcher - log extension host created watcher logic (#248507)

* file watcher - log extension host created watcher logic

* hygiene
This commit is contained in:
Benjamin Pasero
2025-05-09 15:22:10 +02:00
committed by GitHub
parent 21c7938ff7
commit 3c3303a088
2 changed files with 64 additions and 10 deletions
@@ -296,7 +296,7 @@ export abstract class BaseWindow extends Disposable implements IBaseWindow {
case FocusMode.Notify:
if (isMacintosh) {
electron.app.dock.bounce('informational');
electron.app.dock?.bounce('informational');
} else if (isWindows) {
// On Windows, this just flashes the taskbar icon, which is desired
// https://github.com/electron/electron/issues/2867
@@ -14,7 +14,7 @@ import { Disposable, WorkspaceEdit } from './extHostTypes.js';
import { IExtensionDescription } from '../../../platform/extensions/common/extensions.js';
import { FileChangeFilter, FileOperation, IGlobPatterns } from '../../../platform/files/common/files.js';
import { CancellationToken } from '../../../base/common/cancellation.js';
import { ILogService } from '../../../platform/log/common/log.js';
import { ILogService, LogLevel } from '../../../platform/log/common/log.js';
import { IExtHostWorkspace } from './extHostWorkspace.js';
import { Lazy } from '../../../base/common/lazy.js';
import { ExtHostConfigProvider } from './extHostConfiguration.js';
@@ -29,6 +29,9 @@ export interface FileSystemWatcherCreateOptions {
class FileSystemWatcher implements vscode.FileSystemWatcher {
private static IDS = 0;
private readonly id = FileSystemWatcher.IDS++;
private readonly session = Math.random();
private readonly _onDidCreate = new Emitter<vscode.Uri>();
@@ -50,7 +53,16 @@ class FileSystemWatcher implements vscode.FileSystemWatcher {
return Boolean(this._config & 0b100);
}
constructor(mainContext: IMainContext, configuration: ExtHostConfigProvider, workspace: IExtHostWorkspace, extension: IExtensionDescription, dispatcher: Event<FileSystemEvents>, globPattern: string | IRelativePatternDto, options: FileSystemWatcherCreateOptions) {
constructor(
mainContext: IMainContext,
logService: ILogService,
configuration: ExtHostConfigProvider,
workspace: IExtHostWorkspace,
extension: IExtensionDescription,
dispatcher: Event<FileSystemEvents>,
globPattern: string | IRelativePatternDto,
options: FileSystemWatcherCreateOptions
) {
this._config = 0;
if (options.ignoreCreateEvents) {
this._config += 0b001;
@@ -62,6 +74,18 @@ class FileSystemWatcher implements vscode.FileSystemWatcher {
this._config += 0b100;
}
const trace = logService.getLevel() === LogLevel.Trace;
if (trace) {
let patternLogMsg: string;
if (typeof globPattern === 'string') {
patternLogMsg = `'${globPattern}'`;
} else {
patternLogMsg = `base: '${globPattern.base}', pattern: '${globPattern.pattern}'`;
}
logService.trace(`[File Watcher ('API') ${this.id}] createFileSystemWatcher(${patternLogMsg}, ${JSON.stringify(options)})`);
}
const parsedPattern = parse(globPattern);
// 1.64.x behaviour change: given the new support to watch any folder
@@ -81,34 +105,64 @@ class FileSystemWatcher implements vscode.FileSystemWatcher {
const subscription = dispatcher(events => {
if (typeof events.session === 'number' && events.session !== this.session) {
if (trace) {
logService.trace(`[File Watcher ('API') ${this.id}] dispatch(): returning early due to event correlation mismatch`);
}
return; // ignore events from other file watchers that are in correlation mode
}
if (excludeUncorrelatedEvents && typeof events.session === 'undefined') {
if (trace) {
logService.trace(`[File Watcher ('API') ${this.id}] dispatch(): returning early due to event correlation mismatch`);
}
return; // ignore events from other non-correlating file watcher when we are in correlation mode
}
if (!options.ignoreCreateEvents) {
for (const created of events.created) {
const uri = URI.revive(created);
if (parsedPattern(uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
this._onDidCreate.fire(uri);
if (parsedPattern(uri.fsPath)) {
if (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri)) {
this._onDidCreate.fire(uri);
} else {
logService.trace(`[File Watcher ('API') ${this.id}] dispatch(created): ${uri.fsPath} did not match out-of-workspace rule`);
}
} else {
if (trace) {
logService.trace(`[File Watcher ('API') ${this.id}] dispatch(created): ${uri.fsPath} did not match pattern`);
}
}
}
}
if (!options.ignoreChangeEvents) {
for (const changed of events.changed) {
const uri = URI.revive(changed);
if (parsedPattern(uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
this._onDidChange.fire(uri);
if (parsedPattern(uri.fsPath)) {
if (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri)) {
this._onDidChange.fire(uri);
} else {
logService.trace(`[File Watcher ('API') ${this.id}] dispatch(changed): ${uri.fsPath} did not match out-of-workspace rule`);
}
} else {
if (trace) {
logService.trace(`[File Watcher ('API') ${this.id}] dispatch(changed): ${uri.fsPath} did not match pattern`);
}
}
}
}
if (!options.ignoreDeleteEvents) {
for (const deleted of events.deleted) {
const uri = URI.revive(deleted);
if (parsedPattern(uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
this._onDidDelete.fire(uri);
if (parsedPattern(uri.fsPath)) {
if (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri)) {
this._onDidDelete.fire(uri);
} else {
logService.trace(`[File Watcher ('API') ${this.id}] dispatch(deleted): ${uri.fsPath} did not match out-of-workspace rule`);
}
} else {
if (trace) {
logService.trace(`[File Watcher ('API') ${this.id}] dispatch(deleted): ${uri.fsPath} did not match pattern`);
}
}
}
}
@@ -285,7 +339,7 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
//--- file events
createFileSystemWatcher(workspace: IExtHostWorkspace, configProvider: ExtHostConfigProvider, extension: IExtensionDescription, globPattern: vscode.GlobPattern, options: FileSystemWatcherCreateOptions): vscode.FileSystemWatcher {
return new FileSystemWatcher(this._mainContext, configProvider, workspace, extension, this._onFileSystemEvent.event, typeConverter.GlobPattern.from(globPattern), options);
return new FileSystemWatcher(this._mainContext, this._logService, configProvider, workspace, extension, this._onFileSystemEvent.event, typeConverter.GlobPattern.from(globPattern), options);
}
$onFileEvent(events: FileSystemEvents) {