/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * An object which can enter a "broken" state where trying to use it is a UsageError.
 */
export declare class Breakable {
    private readonly name;
    private brokenBy?;
    constructor(name: string);
    /**
     * Throws if the object is in the broken state.
     * @remarks
     * Can use {@link throwIfBroken} to apply this to a method.
     */
    use(): void;
    /**
     * Puts this object into the broken state, and throws an error.
     *
     * @throws If already broken by a different error, throws a UsageError, otherwise throws `brokenBy`.
     */
    break(brokenBy: Error): never;
    /**
     * {@link Breakable.break}, except tolerates `unknown` to be more easily used by catch blocks.
     * @privateRemarks
     * If there is a use-case, this should be made public.
     */
    private rethrowCaught;
    /**
     * Runs code which should break the object if it throws.
     * @remarks
     * This also throws if already broken like {@link Breakable.use}.
     * Any exceptions this catches are re-thrown.
     * Can use {@link breakingMethod} to apply this to a method.
     */
    run<TResult>(breaker: () => TResult): TResult;
    /**
     * Clears the existing broken state.
     * @remarks
     * This is rarely safe to to: it is only ok when all objects using this breaker are known to not have been left in an invalid state.
     * This is pretty much only safe in tests which just were checking a specific error was thrown, and which know that error closepath is actually exception safe.
     */
    clearError(): void;
}
/**
 * Marks an object as being able to be in a broken state (unknown/unspecified/broken state due to unhandled exception).
 * @remarks
 * See decorators {@link breakingMethod} and {@link throwIfBroken} for ease of use.
 */
export interface WithBreakable {
    readonly breaker: Breakable;
}
/**
 * Decorator for methods which should break the object when they throw.
 * @remarks
 * This also throws if already broken like {@link throwIfBroken}.
 * See {@link Breakable.run} for details.
 *
 * This should be used on methods which modify data that could result in an unsupported/broken state if an exception is thrown while modifying.
 * It is ok for breakingMethods to call each-other.
 * @privateRemarks
 * Explicitly capturing the full `Target` type is necessary to make this work with generic methods with unknown numbers of type parameters.
 */
export declare function breakingMethod<Target extends ((...args: any[]) => unknown) & ((this: This, ...args: Args) => Return), This extends WithBreakable, Args extends never[], Return>(target: Target, context?: ClassMethodDecoratorContext<This, Target>): Target;
/**
 * Decorator for methods which should throw if the object is in a broken state.
 * @remarks
 * This should be used on methods which read data that could be invalid when the object is broken.
 * @privateRemarks
 * Explicitly capturing the full `Target` type is necessary to make this work with generic methods with unknown numbers of type parameters.
 */
export declare function throwIfBroken<Target extends ((...args: any[]) => unknown) & ((this: This, ...args: Args) => Return), This extends WithBreakable, Args extends never[], Return>(target: Target, context: ClassMethodDecoratorContext<This, Target>): Target;
/**
 * Decorator for classes which should break when their methods throw.
 * @remarks
 * Applies {@link breakingMethod} to all methods declared directly by class or its base classes.
 * Does not include those on derived classes.
 * Does not include getters or setters, or value properties.
 * Methods already marked as {@link breakingMethod} or {@link throwIfBroken} are unaffected.
 */
export declare function breakingClass<Target extends abstract new (...args: any[]) => WithBreakable>(target: Target, context: ClassDecoratorContext<Target>): Target;
//# sourceMappingURL=breakable.d.ts.map