123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- const createCustomError = require('../utils/createCustomError');
- const generate = require('../definition-syntax/generate');
- const defaultLoc = { offset: 0, line: 1, column: 1 };
- function locateMismatch(matchResult, node) {
- const tokens = matchResult.tokens;
- const longestMatch = matchResult.longestMatch;
- const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null;
- const badNode = mismatchNode !== node ? mismatchNode : null;
- let mismatchOffset = 0;
- let mismatchLength = 0;
- let entries = 0;
- let css = '';
- let start;
- let end;
- for (let i = 0; i < tokens.length; i++) {
- const token = tokens[i].value;
- if (i === longestMatch) {
- mismatchLength = token.length;
- mismatchOffset = css.length;
- }
- if (badNode !== null && tokens[i].node === badNode) {
- if (i <= longestMatch) {
- entries++;
- } else {
- entries = 0;
- }
- }
- css += token;
- }
- if (longestMatch === tokens.length || entries > 1) { // last
- start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css);
- end = buildLoc(start);
- } else {
- start = fromLoc(badNode, 'start') ||
- buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset));
- end = fromLoc(badNode, 'end') ||
- buildLoc(start, css.substr(mismatchOffset, mismatchLength));
- }
- return {
- css,
- mismatchOffset,
- mismatchLength,
- start,
- end
- };
- }
- function fromLoc(node, point) {
- const value = node && node.loc && node.loc[point];
- if (value) {
- return 'line' in value ? buildLoc(value) : value;
- }
- return null;
- }
- function buildLoc({ offset, line, column }, extra) {
- const loc = {
- offset,
- line,
- column
- };
- if (extra) {
- const lines = extra.split(/\n|\r\n?|\f/);
- loc.offset += extra.length;
- loc.line += lines.length - 1;
- loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1;
- }
- return loc;
- }
- const SyntaxReferenceError = function(type, referenceName) {
- const error = createCustomError(
- 'SyntaxReferenceError',
- type + (referenceName ? ' `' + referenceName + '`' : '')
- );
- error.reference = referenceName;
- return error;
- };
- const SyntaxMatchError = function(message, syntax, node, matchResult) {
- const error = createCustomError('SyntaxMatchError', message);
- const {
- css,
- mismatchOffset,
- mismatchLength,
- start,
- end
- } = locateMismatch(matchResult, node);
- error.rawMessage = message;
- error.syntax = syntax ? generate(syntax) : '<generic>';
- error.css = css;
- error.mismatchOffset = mismatchOffset;
- error.mismatchLength = mismatchLength;
- error.message = message + '\n' +
- ' syntax: ' + error.syntax + '\n' +
- ' value: ' + (css || '<empty string>') + '\n' +
- ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
- Object.assign(error, start);
- error.loc = {
- source: (node && node.loc && node.loc.source) || '<unknown>',
- start,
- end
- };
- return error;
- };
- module.exports = {
- SyntaxReferenceError,
- SyntaxMatchError
- };
|