jsonlint.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. 'use strict';
  2. // From: https://github.com/zaach/jsonlint
  3. // Vendored in Jest to avoid jsonlint's transitive dependencies.
  4. /* eslint-disable */
  5. var jsonlint = function () {
  6. var parser = {
  7. trace: function trace() {},
  8. yy: {},
  9. symbols_: {
  10. error: 2,
  11. JSONString: 3,
  12. STRING: 4,
  13. JSONNumber: 5,
  14. NUMBER: 6,
  15. JSONNullLiteral: 7,
  16. NULL: 8,
  17. JSONBooleanLiteral: 9,
  18. TRUE: 10,
  19. FALSE: 11,
  20. JSONText: 12,
  21. JSONValue: 13,
  22. EOF: 14,
  23. JSONObject: 15,
  24. JSONArray: 16,
  25. '{': 17,
  26. '}': 18,
  27. JSONMemberList: 19,
  28. JSONMember: 20,
  29. ':': 21,
  30. ',': 22,
  31. '[': 23,
  32. ']': 24,
  33. JSONElementList: 25,
  34. $accept: 0,
  35. $end: 1
  36. },
  37. terminals_: {
  38. 2: 'error',
  39. 4: 'STRING',
  40. 6: 'NUMBER',
  41. 8: 'NULL',
  42. 10: 'TRUE',
  43. 11: 'FALSE',
  44. 14: 'EOF',
  45. 17: '{',
  46. 18: '}',
  47. 21: ':',
  48. 22: ',',
  49. 23: '[',
  50. 24: ']'
  51. },
  52. productions_: [0, [3, 1], [5, 1], [7, 1], [9, 1], [9, 1], [12, 2], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [15, 2], [15, 3], [20, 3], [19, 1], [19, 3], [16, 2], [16, 3], [25, 1], [25, 3]],
  53. performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {
  54. var $0 = $$.length - 1;
  55. switch (yystate) {
  56. case 1:
  57. // replace escaped characters with actual character
  58. this.$ = yytext.replace(/\\(\\|")/g, '$' + '1').replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\t/g, '\t').replace(/\\v/g, '\v').replace(/\\f/g, '\f').replace(/\\b/g, '\b');
  59. break;
  60. case 2:
  61. this.$ = Number(yytext);
  62. break;
  63. case 3:
  64. this.$ = null;
  65. break;
  66. case 4:
  67. this.$ = true;
  68. break;
  69. case 5:
  70. this.$ = false;
  71. break;
  72. case 6:
  73. return this.$ = $$[$0 - 1];
  74. break;
  75. case 13:
  76. this.$ = {};
  77. break;
  78. case 14:
  79. this.$ = $$[$0 - 1];
  80. break;
  81. case 15:
  82. this.$ = [$$[$0 - 2], $$[$0]];
  83. break;
  84. case 16:
  85. this.$ = {};
  86. this.$[$$[$0][0]] = $$[$0][1];
  87. break;
  88. case 17:
  89. this.$ = $$[$0 - 2];
  90. $$[$0 - 2][$$[$0][0]] = $$[$0][1];
  91. break;
  92. case 18:
  93. this.$ = [];
  94. break;
  95. case 19:
  96. this.$ = $$[$0 - 1];
  97. break;
  98. case 20:
  99. this.$ = [$$[$0]];
  100. break;
  101. case 21:
  102. this.$ = $$[$0 - 2];
  103. $$[$0 - 2].push($$[$0]);
  104. break;
  105. }
  106. },
  107. table: [{
  108. 3: 5,
  109. 4: [1, 12],
  110. 5: 6,
  111. 6: [1, 13],
  112. 7: 3,
  113. 8: [1, 9],
  114. 9: 4,
  115. 10: [1, 10],
  116. 11: [1, 11],
  117. 12: 1,
  118. 13: 2,
  119. 15: 7,
  120. 16: 8,
  121. 17: [1, 14],
  122. 23: [1, 15]
  123. }, { 1: [3] }, { 14: [1, 16] }, { 14: [2, 7], 18: [2, 7], 22: [2, 7], 24: [2, 7] }, { 14: [2, 8], 18: [2, 8], 22: [2, 8], 24: [2, 8] }, { 14: [2, 9], 18: [2, 9], 22: [2, 9], 24: [2, 9] }, { 14: [2, 10], 18: [2, 10], 22: [2, 10], 24: [2, 10] }, { 14: [2, 11], 18: [2, 11], 22: [2, 11], 24: [2, 11] }, { 14: [2, 12], 18: [2, 12], 22: [2, 12], 24: [2, 12] }, { 14: [2, 3], 18: [2, 3], 22: [2, 3], 24: [2, 3] }, { 14: [2, 4], 18: [2, 4], 22: [2, 4], 24: [2, 4] }, { 14: [2, 5], 18: [2, 5], 22: [2, 5], 24: [2, 5] }, { 14: [2, 1], 18: [2, 1], 21: [2, 1], 22: [2, 1], 24: [2, 1] }, { 14: [2, 2], 18: [2, 2], 22: [2, 2], 24: [2, 2] }, { 3: 20, 4: [1, 12], 18: [1, 17], 19: 18, 20: 19 }, {
  124. 3: 5,
  125. 4: [1, 12],
  126. 5: 6,
  127. 6: [1, 13],
  128. 7: 3,
  129. 8: [1, 9],
  130. 9: 4,
  131. 10: [1, 10],
  132. 11: [1, 11],
  133. 13: 23,
  134. 15: 7,
  135. 16: 8,
  136. 17: [1, 14],
  137. 23: [1, 15],
  138. 24: [1, 21],
  139. 25: 22
  140. }, { 1: [2, 6] }, { 14: [2, 13], 18: [2, 13], 22: [2, 13], 24: [2, 13] }, { 18: [1, 24], 22: [1, 25] }, { 18: [2, 16], 22: [2, 16] }, { 21: [1, 26] }, { 14: [2, 18], 18: [2, 18], 22: [2, 18], 24: [2, 18] }, { 22: [1, 28], 24: [1, 27] }, { 22: [2, 20], 24: [2, 20] }, { 14: [2, 14], 18: [2, 14], 22: [2, 14], 24: [2, 14] }, { 3: 20, 4: [1, 12], 20: 29 }, {
  141. 3: 5,
  142. 4: [1, 12],
  143. 5: 6,
  144. 6: [1, 13],
  145. 7: 3,
  146. 8: [1, 9],
  147. 9: 4,
  148. 10: [1, 10],
  149. 11: [1, 11],
  150. 13: 30,
  151. 15: 7,
  152. 16: 8,
  153. 17: [1, 14],
  154. 23: [1, 15]
  155. }, { 14: [2, 19], 18: [2, 19], 22: [2, 19], 24: [2, 19] }, {
  156. 3: 5,
  157. 4: [1, 12],
  158. 5: 6,
  159. 6: [1, 13],
  160. 7: 3,
  161. 8: [1, 9],
  162. 9: 4,
  163. 10: [1, 10],
  164. 11: [1, 11],
  165. 13: 31,
  166. 15: 7,
  167. 16: 8,
  168. 17: [1, 14],
  169. 23: [1, 15]
  170. }, { 18: [2, 17], 22: [2, 17] }, { 18: [2, 15], 22: [2, 15] }, { 22: [2, 21], 24: [2, 21] }],
  171. defaultActions: { 16: [2, 6] },
  172. parseError: function parseError(str, hash) {
  173. throw new Error(str);
  174. },
  175. parse: function parse(input) {
  176. var self = this,
  177. stack = [0],
  178. vstack = [null],
  179. // semantic value stack
  180. lstack = [],
  181. // location stack
  182. table = this.table,
  183. yytext = '',
  184. yylineno = 0,
  185. yyleng = 0,
  186. recovering = 0,
  187. TERROR = 2,
  188. EOF = 1;
  189. //this.reductionCount = this.shiftCount = 0;
  190. this.lexer.setInput(input);
  191. this.lexer.yy = this.yy;
  192. this.yy.lexer = this.lexer;
  193. if (typeof this.lexer.yylloc == 'undefined') this.lexer.yylloc = {};
  194. var yyloc = this.lexer.yylloc;
  195. lstack.push(yyloc);
  196. if (typeof this.yy.parseError === 'function') this.parseError = this.yy.parseError;
  197. function popStack(n) {
  198. stack.length = stack.length - 2 * n;
  199. vstack.length = vstack.length - n;
  200. lstack.length = lstack.length - n;
  201. }
  202. function lex() {
  203. var token;
  204. token = self.lexer.lex() || 1; // $end = 1
  205. // if token isn't its numeric value, convert
  206. if (typeof token !== 'number') {
  207. token = self.symbols_[token] || token;
  208. }
  209. return token;
  210. }
  211. var symbol,
  212. preErrorSymbol,
  213. state,
  214. action,
  215. a,
  216. r,
  217. yyval = {},
  218. p,
  219. len,
  220. newState,
  221. expected;
  222. while (true) {
  223. // retrieve state number from top of stack
  224. state = stack[stack.length - 1];
  225. // use default actions if available
  226. if (this.defaultActions[state]) {
  227. action = this.defaultActions[state];
  228. } else {
  229. if (symbol == null) symbol = lex();
  230. // read action for current state and first input
  231. action = table[state] && table[state][symbol];
  232. }
  233. // handle parse error
  234. _handle_error: if (typeof action === 'undefined' || !action.length || !action[0]) {
  235. if (!recovering) {
  236. // Report error
  237. expected = [];
  238. for (p in table[state]) if (this.terminals_[p] && p > 2) {
  239. expected.push("'" + this.terminals_[p] + "'");
  240. }
  241. var errStr = '';
  242. if (this.lexer.showPosition) {
  243. errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + this.lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ", got '" + this.terminals_[symbol] + "'";
  244. } else {
  245. errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == 1 /*EOF*/
  246. ? 'end of input' : "'" + (this.terminals_[symbol] || symbol) + "'");
  247. }
  248. this.parseError(errStr, {
  249. text: this.lexer.match,
  250. token: this.terminals_[symbol] || symbol,
  251. line: this.lexer.yylineno,
  252. loc: yyloc,
  253. expected: expected
  254. });
  255. }
  256. // just recovered from another error
  257. if (recovering == 3) {
  258. if (symbol == EOF) {
  259. throw new Error(errStr || 'Parsing halted.');
  260. }
  261. // discard current lookahead and grab another
  262. yyleng = this.lexer.yyleng;
  263. yytext = this.lexer.yytext;
  264. yylineno = this.lexer.yylineno;
  265. yyloc = this.lexer.yylloc;
  266. symbol = lex();
  267. }
  268. // try to recover from error
  269. while (1) {
  270. // check for error recovery rule in this state
  271. if (TERROR.toString() in table[state]) {
  272. break;
  273. }
  274. if (state == 0) {
  275. throw new Error(errStr || 'Parsing halted.');
  276. }
  277. popStack(1);
  278. state = stack[stack.length - 1];
  279. }
  280. preErrorSymbol = symbol; // save the lookahead token
  281. symbol = TERROR; // insert generic error symbol as new lookahead
  282. state = stack[stack.length - 1];
  283. action = table[state] && table[state][TERROR];
  284. recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
  285. }
  286. // this shouldn't happen, unless resolve defaults are off
  287. if (action[0] instanceof Array && action.length > 1) {
  288. throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
  289. }
  290. switch (action[0]) {
  291. case 1:
  292. // shift
  293. //this.shiftCount++;
  294. stack.push(symbol);
  295. vstack.push(this.lexer.yytext);
  296. lstack.push(this.lexer.yylloc);
  297. stack.push(action[1]); // push state
  298. symbol = null;
  299. if (!preErrorSymbol) {
  300. // normal execution/no error
  301. yyleng = this.lexer.yyleng;
  302. yytext = this.lexer.yytext;
  303. yylineno = this.lexer.yylineno;
  304. yyloc = this.lexer.yylloc;
  305. if (recovering > 0) recovering--;
  306. } else {
  307. // error just occurred, resume old lookahead f/ before error
  308. symbol = preErrorSymbol;
  309. preErrorSymbol = null;
  310. }
  311. break;
  312. case 2:
  313. // reduce
  314. //this.reductionCount++;
  315. len = this.productions_[action[1]][1];
  316. // perform semantic action
  317. yyval.$ = vstack[vstack.length - len]; // default to $$ = $1
  318. // default location, uses first token for firsts, last for lasts
  319. yyval._$ = {
  320. first_line: lstack[lstack.length - (len || 1)].first_line,
  321. last_line: lstack[lstack.length - 1].last_line,
  322. first_column: lstack[lstack.length - (len || 1)].first_column,
  323. last_column: lstack[lstack.length - 1].last_column
  324. };
  325. r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
  326. if (typeof r !== 'undefined') {
  327. return r;
  328. }
  329. // pop off stack
  330. if (len) {
  331. stack = stack.slice(0, -1 * len * 2);
  332. vstack = vstack.slice(0, -1 * len);
  333. lstack = lstack.slice(0, -1 * len);
  334. }
  335. stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
  336. vstack.push(yyval.$);
  337. lstack.push(yyval._$);
  338. // goto new state = table[STATE][NONTERMINAL]
  339. newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
  340. stack.push(newState);
  341. break;
  342. case 3:
  343. // accept
  344. return true;
  345. }
  346. }
  347. return true;
  348. }
  349. };
  350. /* Jison generated lexer */
  351. var lexer = function () {
  352. var lexer = {
  353. EOF: 1,
  354. parseError: function parseError(str, hash) {
  355. if (this.yy.parseError) {
  356. this.yy.parseError(str, hash);
  357. } else {
  358. throw new Error(str);
  359. }
  360. },
  361. setInput: function (input) {
  362. this._input = input;
  363. this._more = this._less = this.done = false;
  364. this.yylineno = this.yyleng = 0;
  365. this.yytext = this.matched = this.match = '';
  366. this.conditionStack = ['INITIAL'];
  367. this.yylloc = {
  368. first_line: 1,
  369. first_column: 0,
  370. last_line: 1,
  371. last_column: 0
  372. };
  373. return this;
  374. },
  375. input: function () {
  376. var ch = this._input[0];
  377. this.yytext += ch;
  378. this.yyleng++;
  379. this.match += ch;
  380. this.matched += ch;
  381. var lines = ch.match(/\n/);
  382. if (lines) this.yylineno++;
  383. this._input = this._input.slice(1);
  384. return ch;
  385. },
  386. unput: function (ch) {
  387. this._input = ch + this._input;
  388. return this;
  389. },
  390. more: function () {
  391. this._more = true;
  392. return this;
  393. },
  394. less: function (n) {
  395. this._input = this.match.slice(n) + this._input;
  396. },
  397. pastInput: function () {
  398. var past = this.matched.substr(0, this.matched.length - this.match.length);
  399. return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, '');
  400. },
  401. upcomingInput: function () {
  402. var next = this.match;
  403. if (next.length < 20) {
  404. next += this._input.substr(0, 20 - next.length);
  405. }
  406. return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, '');
  407. },
  408. showPosition: function () {
  409. var pre = this.pastInput();
  410. var c = new Array(pre.length + 1).join('-');
  411. return pre + this.upcomingInput() + '\n' + c + '^';
  412. },
  413. next: function () {
  414. if (this.done) {
  415. return this.EOF;
  416. }
  417. if (!this._input) this.done = true;
  418. var token, match, tempMatch, index, col, lines;
  419. if (!this._more) {
  420. this.yytext = '';
  421. this.match = '';
  422. }
  423. var rules = this._currentRules();
  424. for (var i = 0; i < rules.length; i++) {
  425. tempMatch = this._input.match(this.rules[rules[i]]);
  426. if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
  427. match = tempMatch;
  428. index = i;
  429. if (!this.options.flex) break;
  430. }
  431. }
  432. if (match) {
  433. lines = match[0].match(/\n.*/g);
  434. if (lines) this.yylineno += lines.length;
  435. this.yylloc = {
  436. first_line: this.yylloc.last_line,
  437. last_line: this.yylineno + 1,
  438. first_column: this.yylloc.last_column,
  439. last_column: lines ? lines[lines.length - 1].length - 1 : this.yylloc.last_column + match[0].length
  440. };
  441. this.yytext += match[0];
  442. this.match += match[0];
  443. this.yyleng = this.yytext.length;
  444. this._more = false;
  445. this._input = this._input.slice(match[0].length);
  446. this.matched += match[0];
  447. token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]);
  448. if (this.done && this._input) this.done = false;
  449. if (token) return token;else return;
  450. }
  451. if (this._input === '') {
  452. return this.EOF;
  453. } else {
  454. this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: '', token: null, line: this.yylineno });
  455. }
  456. },
  457. lex: function lex() {
  458. var r = this.next();
  459. if (typeof r !== 'undefined') {
  460. return r;
  461. } else {
  462. return this.lex();
  463. }
  464. },
  465. begin: function begin(condition) {
  466. this.conditionStack.push(condition);
  467. },
  468. popState: function popState() {
  469. return this.conditionStack.pop();
  470. },
  471. _currentRules: function _currentRules() {
  472. return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
  473. },
  474. topState: function () {
  475. return this.conditionStack[this.conditionStack.length - 2];
  476. },
  477. pushState: function begin(condition) {
  478. this.begin(condition);
  479. }
  480. };
  481. lexer.options = {};
  482. lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {
  483. var YYSTATE = YY_START;
  484. switch ($avoiding_name_collisions) {
  485. case 0 /* skip whitespace */:
  486. break;
  487. case 1:
  488. return 6;
  489. break;
  490. case 2:
  491. yy_.yytext = yy_.yytext.substr(1, yy_.yyleng - 2);
  492. return 4;
  493. break;
  494. case 3:
  495. return 17;
  496. break;
  497. case 4:
  498. return 18;
  499. break;
  500. case 5:
  501. return 23;
  502. break;
  503. case 6:
  504. return 24;
  505. break;
  506. case 7:
  507. return 22;
  508. break;
  509. case 8:
  510. return 21;
  511. break;
  512. case 9:
  513. return 10;
  514. break;
  515. case 10:
  516. return 11;
  517. break;
  518. case 11:
  519. return 8;
  520. break;
  521. case 12:
  522. return 14;
  523. break;
  524. case 13:
  525. return 'INVALID';
  526. break;
  527. }
  528. };
  529. lexer.rules = [/^(?:\s+)/, /^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/, /^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/, /^(?:\{)/, /^(?:\})/, /^(?:\[)/, /^(?:\])/, /^(?:,)/, /^(?::)/, /^(?:true\b)/, /^(?:false\b)/, /^(?:null\b)/, /^(?:$)/, /^(?:.)/];
  530. lexer.conditions = {
  531. INITIAL: {
  532. rules: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
  533. inclusive: true
  534. }
  535. };
  536. return lexer;
  537. }();
  538. parser.lexer = lexer;
  539. return parser;
  540. }();
  541. exports.parser = jsonlint;
  542. exports.errors = function (input) {
  543. try {
  544. this.parse(input);
  545. } catch (e) {
  546. return e.stack;
  547. }
  548. };
  549. exports.parse = function () {
  550. return jsonlint.parse.apply(jsonlint, arguments);
  551. };
  552. exports.main = function commonjsMain(args) {
  553. if (!args[1]) throw new Error('Usage: ' + args[0] + ' FILE');
  554. if (typeof process !== 'undefined') {
  555. var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), 'utf8');
  556. } else {
  557. var cwd = require('file').path(require('file').cwd());
  558. var source = cwd.join(args[1]).read({ charset: 'utf-8' });
  559. }
  560. return exports.parser.parse(source);
  561. };