import { SourceLocation } from "./types" ; import { repeat } from "./utils" ; export function printLoc ( loc , rawSource , contextLines = 1 ) { const firstIndex = Math . max ( loc . first_line - 1 - contextLines , 0 ) ; const lastIndex = loc . last_line + contextLines ; const sourceLines = rawSource . split ( "\n" ) . slice ( firstIndex , lastIndex ) ; const annotatedLines = sourceLines . map ( ( line , i ) => { const lineNumber = i + firstIndex + 1 ; const inRange = lineNumber >= loc . first_line && lineNumber <= loc . last_line ; const gutter = inRange ? ">" : " " ; return `${ gutter } ${ lineNumber } | ${ line }` ; } ) ; if ( loc . first_line === loc . last_line ) { const padding = repeat ( loc . first_column , " " ) ; const underline = repeat ( loc . last_column - loc . first_column , "^" ) ; const insertIndex = loc . first_line - firstIndex ; annotatedLines . splice ( insertIndex , 0 , `    | ${ padding }${ underline }` ) ; } return annotatedLines . join ( "\n" ) ; } class CompilerError extends Error { loc : SourceLocation ; sourceContext : string ; constructor ( message , loc , rawSource ) { super ( message ) ; this . sourceContext = printLoc ( loc , rawSource ) ; this . loc = loc ; } } class UserError extends CompilerError { } export function createUserError ( message , loc , rawSource ) { return new UserError ( message , loc , rawSource ) ; } export function createCompilerError ( message , loc , rawSource ) { return new CompilerError ( message , loc , rawSource ) ; }