import { StandardizedFilePath } from "./fileSystem" ; import { getSyntaxKindName } from "./helpers" ; import { ts } from "./typescript" ; /** Collection of helper functions that can be used to throw errors. */ export namespace errors { /** Base error class. */ export abstract class BaseError extends Error { private constructor ( public readonly message ) { super ( message ) ; this . message = message ; } } /** Thrown when there is a problem with a provided argument. */ export class ArgumentError extends BaseError { constructor ( argName , message ) { super ( `Argument Error (${ argName }): ${ message }` ) ; } } /** Thrown when an argument is null or whitespace. */ export class ArgumentNullOrWhitespaceError extends ArgumentError { constructor ( argName ) { super ( argName , "Cannot be null or whitespace." ) ; } } /** Thrown when an argument is out of range. */ export class ArgumentOutOfRangeError extends ArgumentError { constructor ( argName , value , range ) { super ( argName , `Range is ${ range [ 0 ] } to ${ range [ 1 ] }, but ${ value } was provided.` ) ; } } /** Thrown when an argument does not match an expected type. */ export class ArgumentTypeError extends ArgumentError { constructor ( argName , expectedType , actualType ) { super ( argName , `Expected type '${ expectedType }', but was '${ actualType }'.` ) ; } } /** Thrown when a file or directory path was not found. */ export class PathNotFoundError extends BaseError { constructor ( public readonly path , prefix = "Path" ) { super ( `${ prefix } not found: ${ path }` ) ; } readonly code : "ENOENT" = "ENOENT" ; } /** Thrown when a directory was not found. */ export class DirectoryNotFoundError extends PathNotFoundError { constructor ( dirPath ) { super ( dirPath , "Directory" ) ; } } /** Thrown when a file was not found. */ export class FileNotFoundError extends PathNotFoundError { constructor ( filePath ) { super ( filePath , "File" ) ; } } /** Thrown when an action was taken that is not allowed. */ export class InvalidOperationError extends BaseError { constructor ( message ) { super ( message ) ; } } /** Thrown when a certain behaviour or feature has not been implemented. */ export class NotImplementedError extends BaseError { constructor ( message = "Not implemented." ) { super ( message ) ; } } /** Thrown when an operation is not supported. */ export class NotSupportedError extends BaseError { constructor ( message ) { super ( message ) ; } } param value param expectedType param argName export function throwIfNotType ( value , expectedType , argName ) { if ( typeof value !== expectedType ) throw new ArgumentTypeError ( argName , expectedType , typeof value ) ; } param value param argName export function throwIfNotString ( value , argName ) { if ( typeof value !== "string" ) throw new ArgumentTypeError ( argName , "string" , typeof value ) ; } param value param argName export function throwIfWhitespaceOrNotString ( value , argName ) { throwIfNotString ( value , argName ) ; if ( value . trim ( ) . length === 0 ) throw new ArgumentNullOrWhitespaceError ( argName ) ; } param value param range param argName export function throwIfOutOfRange ( value , range , argName ) { if ( value < range [ 0 ] || value > range [ 1 ] ) throw new ArgumentOutOfRangeError ( argName , value , range ) ; } param actualRange param range param argName export function throwIfRangeOutOfRange ( actualRange , range , argName ) { if ( actualRange [ 0 ] > actualRange [ 1 ] ) throw new ArgumentError ( argName , `The start of a range must not be greater than the end: [${ actualRange [ 0 ] }, ${ actualRange [ 1 ] }]` ) ; throwIfOutOfRange ( actualRange [ 0 ] , range , argName ) ; throwIfOutOfRange ( actualRange [ 1 ] , range , argName ) ; } param kind export function throwNotImplementedForSyntaxKindError ( kind ) { throw new NotImplementedError ( `Not implemented feature for syntax kind '${ getSyntaxKindName ( kind ) }'.` ) ; } param value param argName export function throwIfNegative ( value , argName ) { if ( value < 0 ) throw new ArgumentError ( argName , "Expected a non-negative value." ) ; } param value param errorMessage export function throwIfNullOrUndefined < T > ( value , errorMessage ) { if ( value == null ) throw new InvalidOperationError ( typeof errorMessage === "string" ? errorMessage : errorMessage ( ) ) ; return value ; } param value export function throwNotImplementedForNeverValueError ( value ) { const node = value as any as { kind : number ; } ; if ( node != null && typeof node . kind === "number" ) return throwNotImplementedForSyntaxKindError ( node . kind ) ; throw new NotImplementedError ( `Not implemented value: ${ JSON . stringify ( value ) }` ) ; } param actual param expected param description export function throwIfNotEqual < T > ( actual , expected , description ) { if ( actual !== expected ) throw new InvalidOperationError ( `Expected ${ actual } to equal ${ expected }. ${ description }` ) ; } param value param errorMessage export function throwIfTrue ( value , errorMessage ) { if ( value === true ) throw new InvalidOperationError ( errorMessage ) ; } }