export function assert()

in compiler/src/model/utils.ts [1264:1306]


export function assert (node: Node | Node[] | undefined, condition: boolean, message: string): asserts condition {
  if (!condition) {
    let file: string = ''
    const code: string[] = []
    if (node != null) {
      node = Array.isArray(node) ? node : [node]

      const sourceFile = node[0].getSourceFile()
      const lines = sourceFile.getEndLineNumber()
      const firstPos = sourceFile.getLineAndColumnAtPos(node[0].getPos())
      // where to find the offending line (and column)
      file = `${node[0].getSourceFile().getFilePath()}:${firstPos.line}:${firstPos.column}`

      for (const n of node) {
        // adds line numbers
        const text = sourceFile.getFullText().split(EOL).map((line, index) => `${index + 1}  ${line}`)
        const start = n.getStartLineNumber()
        const end = n.getEndLineNumber()
        for (let i = start; i <= end; i++) {
          // colors the offending lines in red
          text[i - 1] = chalk.red(text[i - 1])
        }
        // show two lines before and two lines after
        // the offending line(s)
        const startShow = start - 3 > 0 ? (start - 3) : 0
        const endShow = end + 2 <= lines ? (end + 2) : lines
        code.push(text.slice(startShow, endShow).join(EOL))
      }
    }

    // needed to be able to run assertions during testing
    // the test framework expects the compiler to throw
    // an exception insteasd of directly exiting with 1
    if (process.env.TEST_COMPILER === 'true') {
      throw new Error(message)
    }

    console.log('Error:', message)
    if (file.length > 0) console.log('At:', file)
    if (code.length > 0) console.log(`\`\`\`\n${code.join('\n```\n')}\n\`\`\``)
    process.exit(1)
  }
}