UNPKG

2.43 kBJavaScriptView Raw
1'use strict';
2const util = require('util');
3const _ = require('lodash');
4
5
6/**
7 * @typedef {{line: number, col: number}} Pos
8 */
9
10/**
11 * @param {string} html
12 * @param node
13 * @return {Pos}
14 */
15function getLine(html, node) {
16 if (!node) {
17 return {line: 1, col: 1};
18 }
19 const linesUntil = html.substring(0, node.startIndex).split('\n');
20 return {line: linesUntil.length, col: linesUntil[linesUntil.length - 1].length + 1};
21}
22
23function norm(n) {
24 return n === undefined ? -1 : n;
25}
26
27/**
28 * @param {string} message
29 * @param {number=} startOffset
30 * @param {number=} endOffset
31 * @param {number=} line
32 * @param {number=} column
33 * @constructor
34 */
35class RTCodeError extends Error {
36 constructor(message, startOffset, endOffset, line, column) {
37 super();
38 Error.captureStackTrace(this, RTCodeError);
39 this.name = 'RTCodeError';
40 this.message = message || '';
41 this.index = norm(startOffset);
42 this.startOffset = norm(startOffset);
43 this.endOffset = norm(endOffset);
44 this.line = norm(line);
45 this.column = norm(column);
46 }
47}
48
49/**
50 * @type {buildError}
51 */
52RTCodeError.build = buildError;
53RTCodeError.norm = norm;
54
55/**
56 * @param {*} context
57 * @param {*} node
58 * @param {string} msg
59 * @param args
60 * @return {RTCodeError}
61 */
62function buildFormat(context, node, msg, args) {
63 return buildError(context, node, util.format.apply(this, [msg].concat(args)));
64}
65
66/**
67 * @param {*} context
68 * @param {*} node
69 * @param {string} msg
70 * @param {Array.<string>} args
71 * @return {RTCodeError}
72 */
73RTCodeError.buildFormat = _.rest(buildFormat, 3);
74
75/**
76 * @param {*} context
77 * @param {*} node
78 * @param {string} msg
79 * @return {RTCodeError}
80 */
81function buildError(context, node, msg) {
82 const loc = getNodeLoc(context, node);
83 return new RTCodeError(msg, loc.start, loc.end, loc.pos.line, loc.pos.col);
84}
85
86/**
87 * @param context
88 * @param node
89 * @return {{pos:Pos, start:number, end:number}}
90 */
91function getNodeLoc(context, node) {
92 const start = node.startIndex;
93 const pos = getLine(context.html, node);
94 let end;
95 if (node.data) {
96 end = start + node.data.length;
97 } else if (node.next) { // eslint-disable-line
98 end = node.next.startIndex;
99 } else {
100 end = context.html.length;
101 }
102 return {
103 pos,
104 start,
105 end
106 };
107}
108
109module.exports = {
110 RTCodeError,
111 getNodeLoc
112};