Copy semmle-vscode-utils into extension.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from '../vscode-utils/disposable-object';
|
||||
import {
|
||||
WebviewPanel,
|
||||
ExtensionContext,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
import { workspace, Event, EventEmitter, ConfigurationChangeEvent, ConfigurationTarget } from 'vscode';
|
||||
import { DistributionManager } from './distribution';
|
||||
import { logger } from './logging';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as path from 'path';
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
import {
|
||||
commands,
|
||||
Event,
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as cli from './cli';
|
||||
import { ExtensionContext } from 'vscode';
|
||||
import { showAndLogErrorMessage, showAndLogWarningMessage, showAndLogInformationMessage } from './helpers';
|
||||
import { zipArchiveScheme, encodeSourceArchiveUri, decodeSourceArchiveUri } from './archive-filesystem-provider';
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
import { QueryServerConfig } from './config';
|
||||
import { Logger, logger } from './logging';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
|
||||
/**
|
||||
* Base class for "discovery" operations, which scan the file system to find specific kinds of
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as path from 'path';
|
||||
import * as Sarif from 'sarif';
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
import * as vscode from 'vscode';
|
||||
import {
|
||||
Diagnostic,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { window as Window, OutputChannel, Progress, Disposable } from 'vscode';
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { EventEmitter, Event, Uri, WorkspaceFolder, RelativePattern } from 'vscode';
|
||||
import { MultiFileSystemWatcher } from '@github/codeql-vscode-utils';
|
||||
import { MultiFileSystemWatcher } from './vscode-utils/multi-file-system-watcher';
|
||||
import { CodeQLCliServer, QlpacksInfo } from './cli';
|
||||
import { Discovery } from './discovery';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as path from 'path';
|
||||
import { QLPackDiscovery } from './qlpack-discovery';
|
||||
import { Discovery } from './discovery';
|
||||
import { EventEmitter, Event, Uri, RelativePattern, env } from 'vscode';
|
||||
import { MultiFileSystemWatcher } from '@github/codeql-vscode-utils';
|
||||
import { MultiFileSystemWatcher } from './vscode-utils/multi-file-system-watcher';
|
||||
import { CodeQLCliServer } from './cli';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import * as cp from 'child_process';
|
||||
import * as path from 'path';
|
||||
// Import from the specific module within `semmle-vscode-utils`, rather than via `index.ts`, because
|
||||
// we avoid taking an accidental runtime dependency on `vscode` this way.
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils/out/disposable-object';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
import { Disposable } from 'vscode';
|
||||
import { CancellationToken, createMessageConnection, MessageConnection, RequestType } from 'vscode-jsonrpc';
|
||||
import * as cli from './cli';
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
import { TestAdapterRegistrar } from 'vscode-test-adapter-util';
|
||||
import { QLTestFile, QLTestNode, QLTestDirectory, QLTestDiscovery } from './qltest-discovery';
|
||||
import { Event, EventEmitter, CancellationTokenSource, CancellationToken } from 'vscode';
|
||||
import { DisposableObject } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
import { QLPackDiscovery } from './qlpack-discovery';
|
||||
import { CodeQLCliServer } from './cli';
|
||||
import { getOnDiskWorkspaceFolders } from './helpers';
|
||||
|
||||
@@ -2,7 +2,8 @@ import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import { Uri, TextDocumentShowOptions, commands, window } from 'vscode';
|
||||
import { TestTreeNode } from './test-tree-node';
|
||||
import { DisposableObject, UIService } from '@github/codeql-vscode-utils';
|
||||
import { DisposableObject } from './vscode-utils/disposable-object';
|
||||
import { UIService } from './vscode-utils/ui-service';
|
||||
import { TestHub, TestController, TestAdapter, TestRunStartedEvent, TestRunFinishedEvent, TestEvent, TestSuiteEvent } from 'vscode-test-adapter-api';
|
||||
import { QLTestAdapter, getExpectedFile, getActualFile } from './test-adapter';
|
||||
import { logger } from './logging';
|
||||
|
||||
63
extensions/ql-vscode/src/vscode-utils/disposable-object.ts
Normal file
63
extensions/ql-vscode/src/vscode-utils/disposable-object.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Disposable } from "vscode";
|
||||
|
||||
/**
|
||||
* Base class to make it easier to implement a `Disposable` that owns other disposable object.
|
||||
*/
|
||||
export abstract class DisposableObject implements Disposable {
|
||||
private disposables: Disposable[] = [];
|
||||
private tracked?: Set<Disposable> = undefined;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `obj` to a list of objects to dispose when `this` is disposed. Objects added by `push` are
|
||||
* disposed in reverse order of being added.
|
||||
* @param obj The object to take ownership of.
|
||||
*/
|
||||
protected push<T extends Disposable>(obj: T): T {
|
||||
if (obj !== undefined) {
|
||||
this.disposables.push(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `obj` to a set of objects to dispose when `this` is disposed. Objects added by
|
||||
* `track` are disposed in an unspecified order.
|
||||
* @param obj The object to track.
|
||||
*/
|
||||
protected track<T extends Disposable>(obj: T): T {
|
||||
if (obj !== undefined) {
|
||||
if (this.tracked === undefined) {
|
||||
this.tracked = new Set<Disposable>();
|
||||
}
|
||||
this.tracked.add(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes `obj`, which must have been previously added by `track`, from the set of objects to
|
||||
* dispose when `this` is disposed. `obj` itself is disposed.
|
||||
* @param obj The object to stop tracking.
|
||||
*/
|
||||
protected disposeAndStopTracking(obj: Disposable): void {
|
||||
if (obj !== undefined) {
|
||||
this.tracked!.delete(obj);
|
||||
obj.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
if (this.tracked !== undefined) {
|
||||
for (const trackedObject of this.tracked.values()) {
|
||||
trackedObject.dispose();
|
||||
}
|
||||
this.tracked = undefined;
|
||||
}
|
||||
while (this.disposables.length > 0) {
|
||||
this.disposables.pop()!.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { DisposableObject } from './disposable-object';
|
||||
import { EventEmitter, Event, Uri, GlobPattern, workspace } from 'vscode';
|
||||
|
||||
/**
|
||||
* A collection of `FileSystemWatcher` objects. Disposing this object disposes all of the individual
|
||||
* `FileSystemWatcher` objects and their event registrations.
|
||||
*/
|
||||
class WatcherCollection extends DisposableObject {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `FileSystemWatcher` and add it to the collection.
|
||||
* @param pattern The pattern to watch.
|
||||
* @param listener The event listener to be invoked when a watched file is created, changed, or
|
||||
* deleted.
|
||||
* @param thisArgs The `this` argument for the event listener.
|
||||
*/
|
||||
public addWatcher(pattern: GlobPattern, listener: (e: Uri) => any, thisArgs: any): void {
|
||||
const watcher = workspace.createFileSystemWatcher(pattern);
|
||||
this.push(watcher.onDidCreate(listener, thisArgs));
|
||||
this.push(watcher.onDidChange(listener, thisArgs));
|
||||
this.push(watcher.onDidDelete(listener, thisArgs));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to watch multiple patterns in the file system at the same time, reporting all
|
||||
* notifications via a single event.
|
||||
*/
|
||||
export class MultiFileSystemWatcher extends DisposableObject {
|
||||
private readonly _onDidChange = this.push(new EventEmitter<Uri>());
|
||||
private watchers = this.track(new WatcherCollection());
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to be fired when any watched file is created, changed, or deleted.
|
||||
*/
|
||||
public get onDidChange(): Event<Uri> { return this._onDidChange.event; }
|
||||
|
||||
/**
|
||||
* Adds a new pattern to watch.
|
||||
* @param pattern The pattern to watch.
|
||||
*/
|
||||
public addWatch(pattern: GlobPattern): void {
|
||||
this.watchers.addWatcher(pattern, this.handleDidChange, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all existing watchers.
|
||||
*/
|
||||
public clear(): void {
|
||||
this.disposeAndStopTracking(this.watchers);
|
||||
this.watchers = this.track(new WatcherCollection());
|
||||
}
|
||||
|
||||
private handleDidChange(uri: Uri): void {
|
||||
this._onDidChange.fire(uri);
|
||||
}
|
||||
}
|
||||
|
||||
27
extensions/ql-vscode/src/vscode-utils/ui-service.ts
Normal file
27
extensions/ql-vscode/src/vscode-utils/ui-service.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { commands, TreeDataProvider, window } from 'vscode';
|
||||
import { DisposableObject } from './disposable-object';
|
||||
|
||||
/**
|
||||
* A VS Code service that interacts with the UI, including handling commands.
|
||||
*/
|
||||
export class UIService extends DisposableObject {
|
||||
protected constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a command handler with Visual Studio Code.
|
||||
* @param command The ID of the command to register.
|
||||
* @param callback Callback function to implement the command.
|
||||
* @remarks The command handler is automatically unregistered when the service is disposed.
|
||||
*/
|
||||
protected registerCommand(command: string, callback: (...args: any[]) => any): void {
|
||||
this.push(commands.registerCommand(command, callback, this));
|
||||
}
|
||||
|
||||
protected registerTreeDataProvider<T>(viewId: string, treeDataProvider: TreeDataProvider<T>):
|
||||
void {
|
||||
|
||||
this.push(window.registerTreeDataProvider<T>(viewId, treeDataProvider));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user