[d565449] | 1 | var createCustomError = require('../utils/createCustomError');
|
---|
| 2 | var MAX_LINE_LENGTH = 100;
|
---|
| 3 | var OFFSET_CORRECTION = 60;
|
---|
| 4 | var TAB_REPLACEMENT = ' ';
|
---|
| 5 |
|
---|
| 6 | function sourceFragment(error, extraLines) {
|
---|
| 7 | function processLines(start, end) {
|
---|
| 8 | return lines.slice(start, end).map(function(line, idx) {
|
---|
| 9 | var num = String(start + idx + 1);
|
---|
| 10 |
|
---|
| 11 | while (num.length < maxNumLength) {
|
---|
| 12 | num = ' ' + num;
|
---|
| 13 | }
|
---|
| 14 |
|
---|
| 15 | return num + ' |' + line;
|
---|
| 16 | }).join('\n');
|
---|
| 17 | }
|
---|
| 18 |
|
---|
| 19 | var lines = error.source.split(/\r\n?|\n|\f/);
|
---|
| 20 | var line = error.line;
|
---|
| 21 | var column = error.column;
|
---|
| 22 | var startLine = Math.max(1, line - extraLines) - 1;
|
---|
| 23 | var endLine = Math.min(line + extraLines, lines.length + 1);
|
---|
| 24 | var maxNumLength = Math.max(4, String(endLine).length) + 1;
|
---|
| 25 | var cutLeft = 0;
|
---|
| 26 |
|
---|
| 27 | // column correction according to replaced tab before column
|
---|
| 28 | column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
|
---|
| 29 |
|
---|
| 30 | if (column > MAX_LINE_LENGTH) {
|
---|
| 31 | cutLeft = column - OFFSET_CORRECTION + 3;
|
---|
| 32 | column = OFFSET_CORRECTION - 2;
|
---|
| 33 | }
|
---|
| 34 |
|
---|
| 35 | for (var i = startLine; i <= endLine; i++) {
|
---|
| 36 | if (i >= 0 && i < lines.length) {
|
---|
| 37 | lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
|
---|
| 38 | lines[i] =
|
---|
| 39 | (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
|
---|
| 40 | lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
|
---|
| 41 | (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
|
---|
| 42 | }
|
---|
| 43 | }
|
---|
| 44 |
|
---|
| 45 | return [
|
---|
| 46 | processLines(startLine, line),
|
---|
| 47 | new Array(column + maxNumLength + 2).join('-') + '^',
|
---|
| 48 | processLines(line, endLine)
|
---|
| 49 | ].filter(Boolean).join('\n');
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | var SyntaxError = function(message, source, offset, line, column) {
|
---|
| 53 | var error = createCustomError('SyntaxError', message);
|
---|
| 54 |
|
---|
| 55 | error.source = source;
|
---|
| 56 | error.offset = offset;
|
---|
| 57 | error.line = line;
|
---|
| 58 | error.column = column;
|
---|
| 59 |
|
---|
| 60 | error.sourceFragment = function(extraLines) {
|
---|
| 61 | return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
|
---|
| 62 | };
|
---|
| 63 | Object.defineProperty(error, 'formattedMessage', {
|
---|
| 64 | get: function() {
|
---|
| 65 | return (
|
---|
| 66 | 'Parse error: ' + error.message + '\n' +
|
---|
| 67 | sourceFragment(error, 2)
|
---|
| 68 | );
|
---|
| 69 | }
|
---|
| 70 | });
|
---|
| 71 |
|
---|
| 72 | // for backward capability
|
---|
| 73 | error.parseError = {
|
---|
| 74 | offset: offset,
|
---|
| 75 | line: line,
|
---|
| 76 | column: column
|
---|
| 77 | };
|
---|
| 78 |
|
---|
| 79 | return error;
|
---|
| 80 | };
|
---|
| 81 |
|
---|
| 82 | module.exports = SyntaxError;
|
---|