diff --git a/src/formatters.ts b/src/formatters.ts index 17a618a..1087de8 100644 --- a/src/formatters.ts +++ b/src/formatters.ts @@ -1,5 +1,5 @@ import * as vscode from "vscode"; -import { checkHasError, extensionConfiguration, getOutputChannel } from "./utils"; +import { extensionConfiguration, getOutputChannel } from "./utils"; import { ToolCheckFunc, Tool } from "./types"; import * as muon from "./tools/muon"; @@ -28,7 +28,7 @@ async function reloadFormatters(sourceRoot: string, context: vscode.ExtensionCon const props = formatters[name]; const checkResult = await props.check(); - if (checkHasError(checkResult)) { + if (checkResult.isError()) { getOutputChannel().appendLine(`Failed to enable formatter ${name}: ${checkResult.error}`); getOutputChannel().show(true); return disposables; diff --git a/src/linters.ts b/src/linters.ts index 881fb7f..5df7a29 100644 --- a/src/linters.ts +++ b/src/linters.ts @@ -1,5 +1,5 @@ import * as vscode from "vscode"; -import { checkHasError, extensionConfiguration, getOutputChannel } from "./utils"; +import { extensionConfiguration, getOutputChannel } from "./utils"; import { ExtensionConfiguration, LinterConfiguration, ToolCheckFunc, Tool } from "./types"; import * as muon from "./tools/muon"; @@ -39,7 +39,7 @@ async function reloadLinters( const props = linters[name]; const checkResult = await props.check(); - if (checkHasError(checkResult)) { + if (checkResult.isError()) { getOutputChannel().appendLine(`Failed to enable linter ${name}: ${checkResult.error}`); getOutputChannel().show(true); continue; diff --git a/src/tools/muon.ts b/src/tools/muon.ts index 52d6eba..619401b 100644 --- a/src/tools/muon.ts +++ b/src/tools/muon.ts @@ -1,6 +1,6 @@ import * as vscode from "vscode"; import { ExecResult, exec, execFeed, extensionConfiguration, getOutputChannel } from "../utils"; -import { Tool, type ToolCheckResult } from "../types"; +import { Tool, ToolCheckResult } from "../types"; import { Version, type VersionArray } from "../version"; export async function lint(muon: Tool, root: string, document: vscode.TextDocument): Promise { @@ -91,12 +91,12 @@ export async function check(): Promise { } catch (e) { const { error, stdout, stderr } = e as ExecResult; console.log(error); - return { error: error!.message }; + return ToolCheckResult.newError(error!.message); } const line1 = stdout.split("\n")[0].split(" "); if (line1.length !== 2) { - return { error: `Invalid version string: ${line1}` }; + return ToolCheckResult.newError(`Invalid version string: ${line1}`); } const ver = line1[1] @@ -110,5 +110,5 @@ export async function check(): Promise { return Number.parseInt(s); }) as VersionArray; - return { tool: { path: muon_path, version: new Version(ver) } }; + return ToolCheckResult.newTool({ path: muon_path, version: new Version(ver) }); } diff --git a/src/types.ts b/src/types.ts index ab1042a..d13dcb0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -14,7 +14,46 @@ export type ToolCheckErrorResult = { error: string; }; -export type ToolCheckResult = ToolCheckSuccessResult | ToolCheckErrorResult; +type ResultImpl = ToolCheckSuccessResult | ToolCheckErrorResult; + +export class ToolCheckResult { + private readonly result: ResultImpl; + + private constructor(result: ResultImpl) { + this.result = result; + } + + static newError(error: string) { + return new ToolCheckResult({ error }); + } + + static newTool(tool: Tool) { + return new ToolCheckResult({ tool }); + } + + private hasErrorImpl(result: ResultImpl): result is ToolCheckErrorResult { + return !!result.error; + } + + isError(): boolean { + return this.hasErrorImpl(this.result); + } + + get error(): string { + if (!this.hasErrorImpl(this.result)) { + throw new Error("Wrong invocation of getter for 'error', check the state first"); + } + return this.result.error; + } + + get tool(): Tool { + if (this.hasErrorImpl(this.result)) { + throw new Error("Wrong invocation of getter for 'tool', check the state first"); + } + return this.result.tool; + } +} + export type ToolCheckFunc = () => Promise; export type LinterConfiguration = { diff --git a/src/utils.ts b/src/utils.ts index 8e476f7..18aa4ef 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -216,7 +216,3 @@ export function whenFileExists(ctx: vscode.ExtensionContext, file: string, liste export function mesonProgram(): string { return which.sync(extensionConfiguration("mesonPath")); } - -export function checkHasError(result: ToolCheckResult): result is ToolCheckErrorResult { - return !!result.error; -}