stacktrace.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.parseUTSSyntaxError = exports.generateCodeFrame = exports.parseUTSSwiftPluginStacktrace = void 0;
  4. const sourceMap_1 = require("./sourceMap");
  5. const utils_1 = require("./utils");
  6. const splitRE = /\r?\n/;
  7. const uniModulesSwiftUTSRe = /(.*)index.swift:([0-9]+):([0-9]+):\s+error:\s+(.*)/;
  8. async function parseUTSSwiftPluginStacktrace({ stacktrace, sourceRoot, sourceMapFile, }) {
  9. const res = [];
  10. const lines = stacktrace.split(splitRE);
  11. for (let i = 0; i < lines.length; i++) {
  12. const line = lines[i];
  13. const codes = await parseUTSStacktraceLine(line, uniModulesSwiftUTSRe, sourceMapFile, sourceRoot);
  14. if (codes && codes.length) {
  15. res.push(...codes);
  16. }
  17. else {
  18. res.push(line);
  19. }
  20. }
  21. return res.join('\n');
  22. }
  23. exports.parseUTSSwiftPluginStacktrace = parseUTSSwiftPluginStacktrace;
  24. async function parseUTSStacktraceLine(lineStr, re, sourceMapFile, sourceRoot) {
  25. const uniModulesMatches = lineStr.match(re);
  26. if (!uniModulesMatches) {
  27. return;
  28. }
  29. const lines = [];
  30. const [, , line, column, message] = uniModulesMatches;
  31. const originalPosition = await (0, sourceMap_1.originalPositionFor)({
  32. sourceMapFile,
  33. line: parseInt(line),
  34. column: parseInt(column),
  35. withSourceContent: true,
  36. });
  37. if (originalPosition.source && originalPosition.sourceContent) {
  38. lines.push(`${message}`);
  39. lines.push(`at ${originalPosition.source.split('?')[0]}:${originalPosition.line}:${originalPosition.column}`);
  40. if (originalPosition.line !== null && originalPosition.column !== null) {
  41. lines.push(generateCodeFrame(originalPosition.sourceContent, {
  42. line: originalPosition.line,
  43. column: originalPosition.column,
  44. }).replace(/\t/g, ' '));
  45. }
  46. }
  47. else {
  48. lines.push(lineStr);
  49. }
  50. return lines;
  51. }
  52. const range = 2;
  53. function posToNumber(source, pos) {
  54. if (typeof pos === 'number')
  55. return pos;
  56. const lines = source.split(splitRE);
  57. const { line, column } = pos;
  58. let start = 0;
  59. for (let i = 0; i < line - 1; i++) {
  60. start += lines[i].length + 1;
  61. }
  62. return start + column;
  63. }
  64. function generateCodeFrame(source, start = 0, end) {
  65. start = posToNumber(source, start);
  66. end = end || start;
  67. const lines = source.split(splitRE);
  68. let count = 0;
  69. const res = [];
  70. for (let i = 0; i < lines.length; i++) {
  71. count += lines[i].length + 1;
  72. if (count >= start) {
  73. for (let j = i - range; j <= i + range || end > count; j++) {
  74. if (j < 0 || j >= lines.length)
  75. continue;
  76. const line = j + 1;
  77. res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
  78. const lineLength = lines[j].length;
  79. if (j === i) {
  80. // push underline
  81. const pad = start - (count - lineLength) + 1;
  82. const length = Math.max(1, end > count ? lineLength - pad : end - start);
  83. res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
  84. }
  85. else if (j > i) {
  86. if (end > count) {
  87. const length = Math.max(Math.min(end - count, lineLength), 1);
  88. res.push(` | ` + '^'.repeat(length));
  89. }
  90. count += lineLength + 1;
  91. }
  92. }
  93. break;
  94. }
  95. }
  96. return res.join('\n');
  97. }
  98. exports.generateCodeFrame = generateCodeFrame;
  99. function parseUTSSyntaxError(error, inputDir) {
  100. if (error instanceof Error) {
  101. error = error.message + (error.stack ? `\n` + error.stack : ``);
  102. }
  103. let msg = String(error).replace(/\t/g, ' ');
  104. let res = null;
  105. const syntaxErrorRe = /(,-\[(.*):(\d+):(\d+)\])/g;
  106. while ((res = syntaxErrorRe.exec(msg))) {
  107. const [row, filename, line, column] = res.slice(1);
  108. msg = msg.replace(row, `at ${(0, utils_1.relative)(filename.split('?')[0], inputDir)}:${parseInt(line) + 1}:${column}`);
  109. }
  110. return msg;
  111. }
  112. exports.parseUTSSyntaxError = parseUTSSyntaxError;