Как я могу скрыть вызов функции из переданного кода с использованием исходных карт?
Скажем, у меня есть язык, который выглядит как
print "Hello World"
который преобразуется в
var $__Helpers = {
print: function(s) {
if (typeof s != 'string')
throw new TypeError('String expected');
console.log(s);
}
};
$__Helpers.print("Hello World");
Если пользователь этого языка делает
print 5
a TypeError будет выбрано $__Helpers.print
, говорящим "String expected". Я хочу, чтобы инструменты разработчика отображали строку print 5
как исходный вызов этой ошибки. Я знаю, как получить исходную карту, чтобы показать стек вызовов, который выглядит как
transpiled_script.js:2
original_script.os:1
где transpiled_script.js:2
- script и номер строки для вызова функции $__Helpers.print
, а original_script.os:1
- это script и номер строки для вызова print 5
. Я хочу, чтобы инструменты dev просто игнорировали верхний вызов transpiled_script.js
(который является только деталью реализации моего транспилятора) и показывают только вызов из исходного script (который является частью, которую они должны отлаживать в своих собственных script).
Я явно не могу просто сопоставить transpiled_script.js:2
с original_script.os:1
, потому что внутри original_script.os
может быть несколько вызовов print
, поэтому это не отношение 1 к 1.
Есть ли способ сделать это?
(Я использую escodegen для генерации моего источника и моей исходной карты (escodegen использует модуль Node mozilla/source-map), поэтому для того, чтобы сказать, что escodegen или mozilla/source-map сделали это, было бы идеально, но я могу переопределить вывод escodegen, если это невозможно.)
Ответы
Ответ 1
Вы можете разделить трассировку и напечатать требуемые строки
var $__Helpers = {
print: function(s) {
if (typeof s != 'string'){
var err = new TypeError('String expected');
var trace = err.stack.split('\n')
console.error(trace[0]); // TypeError: string expected
console.error(trace[2]); // the line who called the function, probably
//original_script.os:1, or whatever line number the call was from
//quit the script
}
console.log(s);
} };
EDIT: лучшее решение - заменить след ошибки, чем выбросить, теперь код выглядит следующим образом:
var $__Helpers = {
print: function(s) {
if (typeof s != 'string'){
var err = new TypeError('String expected: Got'+s);
err.stack = err.stack.replace(/\n.*transpiled_script\.js.*?\n/g,"\n");
throw err;
}
console.log(s);
} };
это тоже будет работать для ошибок в вложенных вызовах.