Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 2x 2x 2x 2x 2x 2x 2x 2x 9510x 9510x 9510x 2x 2x 2x 2x 2x 2x 1754x 1754x 1754x 1754x 1754x 1754x 1754x 1754x 7756x 7756x 7756x 1754x 1754x 1754x 1754x 6002x 1754x 1754x 1754x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1759x 1759x 1759x 1759x 1759x 1759x 1759x 1759x 1759x 1759x 1759x 1759x 1756x 1756x 1759x 1759x 1754x 1754x 1754x 1754x 1754x 1754x 1754x 1759x 1759x 1759x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1759x 1759x 913x 913x 913x 913x 913x 913x 913x 913x 913x 913x 1759x | /** @import { Location } from 'locate-character' */ import * as state from '../state.js'; const regex_tabs = /^\t+/; /** * @param {string} str */ function tabs_to_spaces(str) { return str.replace(regex_tabs, (match) => match.split('\t').join(' ')); } /** * @param {string} source * @param {number} line * @param {number} column */ function get_code_frame(source, line, column) { const lines = source.split('\n'); const frame_start = Math.max(0, line - 2); const frame_end = Math.min(line + 3, lines.length); const digits = String(frame_end + 1).length; return lines .slice(frame_start, frame_end) .map((str, i) => { const is_error_line = frame_start + i === line; const line_num = String(i + frame_start + 1).padStart(digits, ' '); if (is_error_line) { const indicator = ' '.repeat(digits + 2 + tabs_to_spaces(str.slice(0, column)).length) + '^'; return `${line_num}: ${tabs_to_spaces(str)}\n${indicator}`; } return `${line_num}: ${tabs_to_spaces(str)}`; }) .join('\n'); } /** * @typedef {{ * code: string; * message: string; * filename?: string; * start?: Location; * end?: Location; * position?: [number, number]; * frame?: string; * }} ICompileDiagnostic */ /** @implements {ICompileDiagnostic} */ export class CompileDiagnostic extends Error { name = 'CompileDiagnostic'; /** * @param {string} code * @param {string} message * @param {[number, number] | undefined} position */ constructor(code, message, position) { super(message); this.code = code; if (state.filename) { this.filename = state.filename; } if (position) { this.position = position; this.start = state.locator(position[0]); this.end = state.locator(position[1]); if (this.start && this.end) { this.frame = get_code_frame(state.source, this.start.line - 1, this.end.column); } } } toString() { let out = `${this.code}: ${this.message}`; if (this.filename) { out += `\n${this.filename}`; if (this.start) { out += `:${this.start.line}:${this.start.column}`; } } if (this.frame) { out += `\n${this.frame}`; } return out; } toJSON() { return { code: this.code, message: this.message, filename: this.filename, start: this.start, end: this.end, position: this.position, frame: this.frame }; } } |