Name updates.

This commit is contained in:
Anders Starcke Henriksen
2023-03-15 11:52:30 +01:00
parent 52b00fe434
commit 5303ec67cb
13 changed files with 65 additions and 59 deletions

View File

@@ -3,7 +3,7 @@ import { Disposable } from "../pure/disposable-object";
import { AppEventEmitter } from "./events";
import { Logger } from "./logging";
import { Memento } from "./memento";
import { ExtensionCommandManager } from "./commands";
import { AppCommandManager } from "./commands";
export interface App {
createEventEmitter<T>(): AppEventEmitter<T>;
@@ -16,7 +16,7 @@ export interface App {
readonly workspaceStoragePath?: string;
readonly workspaceState: Memento;
readonly credentials: Credentials;
readonly commandManager: ExtensionCommandManager;
readonly commands: AppCommandManager;
}
export enum AppMode {

View File

@@ -7,8 +7,8 @@ import { CommandManager } from "../packages/commands";
* the implementation in the corresponding `getCommands` function.
*/
// Commands directly in the extension
export type ExtensionCommands = {
// Base commands not tied directly to a module like e.g. variant analysis.
export type BaseCommands = {
"codeQL.openDocumentation": () => Promise<void>;
};
@@ -19,6 +19,6 @@ export type VariantAnalysisCommands = {
) => Promise<void>;
};
export type AllCommands = ExtensionCommands & VariantAnalysisCommands;
export type AllCommands = BaseCommands & VariantAnalysisCommands;
export type ExtensionCommandManager = CommandManager<AllCommands>;
export type AppCommandManager = CommandManager<AllCommands>;

View File

@@ -3,16 +3,23 @@ import { commandRunner } from "../../commandRunner";
import { CommandFunction, CommandManager } from "../../packages/commands";
/**
* Intializes a command manager for VSCode, wrapping the commandRunner
* Create a command manager for VSCode, wrapping the commandRunner
* and vscode.executeCommand.
*/
export function initializeVSCodeCommandManager<
export function createVSCodeCommandManager<
Commands extends Record<string, CommandFunction>,
>(): CommandManager<Commands> {
return new CommandManager(commandRunner, wrappedExecuteCommand);
return new CommandManager(commandRunner, wrapExecuteCommand);
}
async function wrappedExecuteCommand<
/**
* wrapExecuteCommand wraps commands.executeCommand to satisfy that the
* type is a Promise. Type script does not seem to be smart enough
* to figure out that `ReturnType<Commands[CommandName]>` is actually
* a Promise, so we need to add a second layer of wrapping and unwrapping
* (The `Promise<Awaited<` part) to get the right types.
*/
async function wrapExecuteCommand<
Commands extends Record<string, CommandFunction>,
CommandName extends keyof Commands & string = keyof Commands & string,
>(

View File

@@ -6,19 +6,19 @@ import { AppEventEmitter } from "../events";
import { extLogger, Logger } from "../logging";
import { Memento } from "../memento";
import { VSCodeAppEventEmitter } from "./events";
import { ExtensionCommandManager } from "../commands";
import { initializeVSCodeCommandManager } from "./commands";
import { AppCommandManager } from "../commands";
import { createVSCodeCommandManager } from "./commands";
export class ExtensionApp implements App {
public readonly credentials: VSCodeCredentials;
public readonly commandManager: ExtensionCommandManager;
public readonly commands: AppCommandManager;
public constructor(
public readonly extensionContext: vscode.ExtensionContext,
) {
this.credentials = new VSCodeCredentials();
this.commandManager = initializeVSCodeCommandManager();
extensionContext.subscriptions.push(this.commandManager);
this.commands = createVSCodeCommandManager();
extensionContext.subscriptions.push(this.commands);
}
public get extensionPath(): string {

View File

@@ -136,7 +136,7 @@ import { RepositoriesFilterSortStateWithIds } from "./pure/variant-analysis-filt
import { DbModule } from "./databases/db-module";
import { redactableError } from "./pure/errors";
import { QueryHistoryDirs } from "./query-history/query-history-dirs";
import { AllCommands, ExtensionCommands } from "./common/commands";
import { AllCommands, BaseCommands } from "./common/commands";
/**
* extension.ts
@@ -168,7 +168,10 @@ let isInstallingOrUpdatingDistribution = false;
const extensionId = "GitHub.vscode-codeql";
const extension = extensions.getExtension(extensionId);
function getCommands(): ExtensionCommands {
/**
* Return all commands that are not tied to the more specific managers.
*/
function getCommands(): BaseCommands {
return {
"codeQL.openDocumentation": async () => {
await env.openExternal(Uri.parse("https://codeql.github.com/docs/"));
@@ -1206,10 +1209,7 @@ async function activateWithInstalledDistribution(
};
for (const [commandName, command] of Object.entries(allCommands)) {
app.commandManager.registerCommand(
commandName as keyof AllCommands,
command,
);
app.commands.register(commandName as keyof AllCommands, command);
}
ctx.subscriptions.push(

View File

@@ -5,9 +5,7 @@
* and then allow other parts to call those commands in a well-typed manner.
*/
export interface Disposable {
dispose(): void;
}
import { Disposable } from "./Disposable";
/**
* A command function is a completely untyped command.
@@ -32,7 +30,7 @@ export class CommandManager<
constructor(
private readonly commandRegister: <T extends CommandName>(
commandName: T,
definition: Commands[T],
fn: Commands[T],
) => Disposable,
private readonly commandExecute: <T extends CommandName>(
commandName: T,
@@ -43,7 +41,7 @@ export class CommandManager<
/**
* Register a command with the specified name and implementation.
*/
registerCommand<T extends CommandName>(
register<T extends CommandName>(
commandName: T,
definition: Commands[T],
): void {
@@ -53,7 +51,7 @@ export class CommandManager<
/**
* Execute a command with the specified name and the provided arguments.
*/
executeCommand<T extends CommandName>(
execute<T extends CommandName>(
commandName: T,
...args: Parameters<Commands[T]>
): Promise<Awaited<ReturnType<Commands[T]>>> {

View File

@@ -0,0 +1,7 @@
/**
* This interface mirrors the vscode.Disaposable class, so that
* the command manager does not depend on vscode directly.
*/
export interface Disposable {
dispose(): void;
}

View File

@@ -62,10 +62,7 @@ import { URLSearchParams } from "url";
import { DbManager } from "../databases/db-manager";
import { App } from "../common/app";
import { redactableError } from "../pure/errors";
import {
ExtensionCommandManager,
VariantAnalysisCommands,
} from "../common/commands";
import { AppCommandManager, VariantAnalysisCommands } from "../common/commands";
export class VariantAnalysisManager
extends DisposableObject
@@ -135,8 +132,8 @@ export class VariantAnalysisManager
};
}
get commandManager(): ExtensionCommandManager {
return this.app.commandManager;
get commandManager(): AppCommandManager {
return this.app.commands;
}
public async runVariantAnalysis(

View File

@@ -2,7 +2,7 @@ import {
VariantAnalysis,
VariantAnalysisScannedRepositoryState,
} from "./shared/variant-analysis";
import { ExtensionCommandManager } from "../common/commands";
import { AppCommandManager } from "../common/commands";
export interface VariantAnalysisViewInterface {
variantAnalysisId: number;
@@ -12,7 +12,7 @@ export interface VariantAnalysisViewInterface {
export interface VariantAnalysisViewManager<
T extends VariantAnalysisViewInterface,
> {
commandManager: ExtensionCommandManager;
commandManager: AppCommandManager;
registerView(view: T): void;
unregisterView(view: T): void;

View File

@@ -145,7 +145,7 @@ export class VariantAnalysisView
);
break;
case "openLogs":
await this.manager.commandManager.executeCommand(
await this.manager.commandManager.execute(
"codeQL.openVariantAnalysisLogs",
this.variantAnalysisId,
);

View File

@@ -6,7 +6,7 @@ import { createMockLogger } from "./loggerMock";
import { createMockMemento } from "../mock-memento";
import { testCredentialsWithStub } from "../factories/authentication";
import { Credentials } from "../../src/common/authentication";
import { ExtensionCommandManager } from "../../src/common/commands";
import { AppCommandManager } from "../../src/common/commands";
import { createMockCommandManager } from "./commandsMock";
export function createMockApp({
@@ -17,7 +17,7 @@ export function createMockApp({
executeCommand = jest.fn(() => Promise.resolve()),
workspaceState = createMockMemento(),
credentials = testCredentialsWithStub(),
commandManager = createMockCommandManager(),
commands = createMockCommandManager(),
}: {
extensionPath?: string;
workspaceStoragePath?: string;
@@ -26,7 +26,7 @@ export function createMockApp({
executeCommand?: () => Promise<void>;
workspaceState?: Memento;
credentials?: Credentials;
commandManager?: ExtensionCommandManager;
commands?: AppCommandManager;
}): App {
return {
mode: AppMode.Test,
@@ -39,7 +39,7 @@ export function createMockApp({
createEventEmitter,
executeCommand,
credentials,
commandManager,
commands,
};
}

View File

@@ -1,9 +1,6 @@
import { ExtensionCommandManager } from "../../src/common/commands";
import {
CommandFunction,
CommandManager,
Disposable,
} from "../../src/packages/commands";
import { AppCommandManager } from "../../src/common/commands";
import { CommandFunction, CommandManager } from "../../src/packages/commands";
import { Disposable } from "../../src/packages/commands/Disposable";
export function createMockCommandManager({
registerCommand = jest.fn(),
@@ -11,6 +8,6 @@ export function createMockCommandManager({
}: {
registerCommand?: (commandName: string, fn: CommandFunction) => Disposable;
executeCommand?: (commandName: string, ...args: any[]) => Promise<any>;
} = {}): ExtensionCommandManager {
} = {}): AppCommandManager {
return new CommandManager(registerCommand, executeCommand);
}

View File

@@ -11,7 +11,7 @@ describe("CommandManager", () => {
jest.fn(),
);
const myCommand = jest.fn();
commandManager.registerCommand("abc", myCommand);
commandManager.register("abc", myCommand);
expect(commandRegister).toHaveBeenCalledTimes(1);
expect(commandRegister).toHaveBeenCalledWith("abc", myCommand);
});
@@ -28,22 +28,22 @@ describe("CommandManager", () => {
);
// @ts-expect-error wrong command name should give a type error
commandManager.registerCommand("abc", jest.fn());
commandManager.register("abc", jest.fn());
commandManager.registerCommand(
commandManager.register(
"codeQL.openVariantAnalysisLogs",
// @ts-expect-error wrong function parameter type should give a type error
async (variantAnalysisId: string): Promise<number> => 10,
);
commandManager.registerCommand(
commandManager.register(
"codeQL.openVariantAnalysisLogs",
// @ts-expect-error wrong function return type should give a type error
async (variantAnalysisId: number): Promise<string> => "hello",
);
// Working types
commandManager.registerCommand(
commandManager.register(
"codeQL.openVariantAnalysisLogs",
async (variantAnalysisId: number): Promise<number> =>
variantAnalysisId * 10,
@@ -61,8 +61,8 @@ describe("CommandManager", () => {
commandRegister,
jest.fn(),
);
commandManager.registerCommand("abc", jest.fn());
commandManager.registerCommand("def", jest.fn());
commandManager.register("abc", jest.fn());
commandManager.register("def", jest.fn());
expect(dispose1).not.toHaveBeenCalled();
expect(dispose2).not.toHaveBeenCalled();
commandManager.dispose();
@@ -76,7 +76,7 @@ describe("CommandManager", () => {
jest.fn(),
commandExecute,
);
const result = await commandManager.executeCommand("abc", "hello", true);
const result = await commandManager.execute("abc", "hello", true);
expect(result).toEqual(7);
expect(commandExecute).toHaveBeenCalledTimes(1);
expect(commandExecute).toHaveBeenCalledWith("abc", "hello", true);
@@ -94,18 +94,18 @@ describe("CommandManager", () => {
);
// @ts-expect-error wrong command name should give a type error
await commandManager.executeCommand("abc", 4);
await commandManager.execute("abc", 4);
await commandManager.executeCommand(
await commandManager.execute(
"codeQL.openVariantAnalysisLogs",
// @ts-expect-error wrong argument type should give a type error
"xyz",
);
// @ts-expect-error wrong number of arguments should give a type error
await commandManager.executeCommand("codeQL.openVariantAnalysisLogs", 2, 3);
await commandManager.execute("codeQL.openVariantAnalysisLogs", 2, 3);
// Working types
await commandManager.executeCommand("codeQL.openVariantAnalysisLogs", 7);
await commandManager.execute("codeQL.openVariantAnalysisLogs", 7);
});
});