Comments (45)
Just landed ESTrace based on our talk π .
from putout.
Also I don't think you should log
arguments
inevents
other thenenter
. Here is how it looks like:
I was working towards that... baby steps :)
from putout.
This is super awesome. I've never had this level of detail in my logging.
from putout.
Looks like this is related to StringLiteral
used as id
to ClassMethod
:
async "formatted-bibliography"(citations) {
const format = Zotero.Prefs.get("export.quickCopy.setting");
if (Zotero.QuickCopy.unserializeSetting(format).mode !== "bibliography") {
throw new Error(`formatted-bibliography requires the Zotero default quick-copy format to be set to a citation style; it is currently ${format}`);
}
const items = await getItemsAsync(citations.map((item) => item.id));
return Zotero.QuickCopy.getContentFromItems(items, format, null, false).text;
}
We should update getName
with:
function getName(path) {
if (path.isClassMethod()) {
const {name, value} = path.node.key;
return name || value;
}
if (path.isFunctionDeclaration()) {
return path.node.id.name;
}
const {line} = path.node.loc.start;
return `<anonymous:${line}>`;
}
So it supported not only Identifier
with name
property but also StringLiteral
with property value
.
from putout.
Works like a charm!
Can I send data to the plugin? I'd like to add the filename in addition to the line number, and I understand I can add that as a FILENAME
replacement on buildLogEnter
etc, but I don't know how to get the value for FILENAME
in. Or should I just declare module.exports.FILENAME
and set that from outside the plugin (which works)?
edit: this is so incredibly rad.
from putout.
Ah no I didn't mean get the filename from the plugin, but to the plugin, indeed with an options object or some such. Right now I'm just setting the filename on the plugin and that works.
from putout.
It gets past the previous error, but I'm hitting https://gist.github.com/69975f9fdfab6606577be925c2df5004
Fixed with coderaiser/estrace@fa4f792. Landed in estrace v1.6.1 π . Is it works for you?
from putout.
Yep, works perfectly! Really needed this for a bug I'm trying to diagnose right now, thanks!
from putout.
I was already satisfied, but I don't know if you want user to close issues or not (I don't on my own repos)
from putout.
It will be something like this:
const {template} = require('putout');
const buildLog = template(`console.log('NAME', arguments)`);
module.exports.fix = (path) => {
const {body} = path.node.body;
const NAME = getName(path);
body.unshift(buildLog({
NAME,
}));
};
module.exports.traverse = ({push}) => ({
Function(path) {
push(path);
console.log(path.node.body);
}
});
function getName(path) {
if (path.isClassMethod())
return path.node.key.name;
if (path.isFunctionDeclaration())
return path.node.id.name;
return '<undetermined>';
}
You can check this out on putout editor, it will look this way:
from putout.
Nice!
I forgot that the logger I can use only accepts a single string, so I tried to change it into
const buildLog = template(`console.log('NAME' + '(' + JSON.stringify(Array.from(arguments)) + ')')`);
which is not accepted in the putout editor, but if I use
const buildLog = template(`console.log('NAME' + '(' + (Array.from(arguments)) + ')')`);
it is -- ideas what is the issue here?
I also just realized I can have enter and exit logging by changing
function X() {
console.log('hello')
}
into
function X() {
console.log('enter X')
try {
console.log('hello')
} finally {
console.log('exit X')
}
}
help very much appreciated.
from putout.
ideas what is the issue here?
By default
, @babel/template uses CAMEL_CASED
names as substitutions, so JSON
should be defined, the simplest way to handle it define JSON
with:
const {template} = require('putout');
const JSON = 'JSON'
const buildLog = template(`console.log('NAME' + '(' + JSON.stringify(Array.from(arguments)) + ')')`);
module.exports.fix = (path) => {
const {body} = path.node.body;
const NAME = getName(path);
body.unshift(buildLog({
NAME,
JSON,
}));
};
module.exports.traverse = ({push}) => ({
Function(path) {
push(path);
console.log(path.node.body);
}
});
function getName(path) {
if (path.isClassMethod())
return path.node.key.name;
if (path.isFunctionDeclaration())
return path.node.id.name;
return '<undetermined>';
}
I also just realized I can have
enter
andexit
logging by changing
Yes, you can even log error
events :). And we can simplify code a bit converting codemod
to Includer, there is a rule convert-traverse-to-include
in @putout/plugin-putout, you can use it while developing locally. Also this code uses Builders from @babel/types to build try-catch
statement.
Here is the code:
const {template, types} = require('putout');
const {tryStatement, catchClause, BlockStatement, Identifier} = types;
const JSON = 'JSON'
const buildLog = template(`console.log('TYPE' + 'NAME' + '(' + JSON.stringify(Array.from(arguments)) + ')')`);
module.exports.include = () => [
'Function',
];
module.exports.fix = (path) => {
const NAME = getName(path);
const enterLog = buildLog({
NAME,
JSON,
TYPE: 'enter',
});
const exitLog = buildLog({
NAME,
JSON,
TYPE: 'exit',
});
const errorLog = buildLog({
NAME,
JSON,
TYPE: 'error',
});
const catchNode = catchClause(Identifier('error'), BlockStatement([errorLog]));
const tryNode = tryStatement(path.node.body, catchNode, BlockStatement([exitLog]));
const bodyPath = path.get('body');
bodyPath.replaceWith(BlockStatement([tryNode]));
bodyPath.node.body.unshift(enterLog);
};
function getName(path) {
if (path.isClassMethod())
return path.node.key.name;
if (path.isFunctionDeclaration())
return path.node.id.name;
return '<undetermined>';
}
from putout.
It can be even simplified a bit if we use @babel/template
to build try-catch
statement. Also we use replaceWith
from operator it also has some helper methods which can be useful while working on codemod
, they try to preserve any comment a little bit more accurate then babel
and recast
.
const {template, types, operator} = require('putout');
const {replaceWith} = operator;
const {BlockStatement, ContinueStatement} = types;
const buildLog = template(`console.log('TYPE' + 'NAME' + '(' + JSON.stringify(Array.from(arguments)) + ')')`);
const buildTryCatch = template(`try {
BLOCK;
} catch(error) {
CATCH;
} finally {
FINALLY;
}
`);
module.exports.include = () => [
'Function',
];
module.exports.fix = (path) => {
const name = getName(path);
const enterLog = buildLogEvent(name, 'enter');
const exitLog = buildLogEvent(name, 'exit');
const errorLog = buildLogEvent(name, 'error');
const bodyPath = path.get('body');
replaceWith(bodyPath, BlockStatement([buildTryCatch({
BLOCK: path.node.body.body,
CATCH: errorLog,
FINALLY: exitLog,
})]));
bodyPath.node.body.unshift(enterLog);
};
function getName(path) {
if (path.isClassMethod())
return path.node.key.name;
if (path.isFunctionDeclaration())
return path.node.id.name;
return '<undetermined>';
}
function buildLogEvent(name, type) {
return buildLog({
NAME: name,
TYPE: type,
JSON: 'JSON',
});
}
from putout.
The catch should re-throw the error though, otherwise the flow of execution would be changed:
const {template, types, operator} = require('putout');
const {replaceWith} = operator;
const {BlockStatement, ContinueStatement} = types;
const buildLog = template(`console.log('TYPE' + ' ' + 'NAME' + '(' + JSON.stringify(Array.from(arguments)) + ')')`);
const buildLogException = template(`console.log('TYPE' + ' ' + 'NAME' + ': ' + trace$error.message); throw trace$error`);
const buildTryCatch = template(`try {
BLOCK;
} catch(trace$error) {
CATCH;
} finally {
FINALLY;
}
`);
module.exports.include = () => [
'Function',
];
module.exports.fix = (path) => {
const name = getName(path);
const enterLog = buildLogEvent(name, 'enter');
const exitLog = buildLogEvent(name, 'exit');
const errorLog = buildLogExceptionEvent(name, 'error');
const bodyPath = path.get('body');
replaceWith(bodyPath, BlockStatement([buildTryCatch({
BLOCK: path.node.body.body,
CATCH: errorLog,
FINALLY: exitLog,
})]));
bodyPath.node.body.unshift(enterLog);
};
function getName(path) {
if (path.isClassMethod())
return path.node.key.name;
if (path.isFunctionDeclaration())
return path.node.id.name;
return '<undetermined>';
}
function buildLogEvent(name, type) {
return buildLog({
NAME: name,
TYPE: type,
JSON: 'JSON',
});
}
function buildLogExceptionEvent(name, type) {
return buildLogException({
NAME: name,
TYPE: type,
});
}
arrow functions don't have names, but would it be possible to do the same for those and log the position (assuming the parser makes that information available)? For a start I tried changing the include
to
module.exports.include = () => [
'Function',
'ArrowFunctionExpression',
];
but that got me real wacky results for arrow functions.
from putout.
Yes it is possible, no need to add ArrowFunctionExpression
and FunctionExpression
to include
, they covered by Function
, but you can use line number
in logs
this way:
const {template, types, operator} = require('putout');
const {replaceWith} = operator;
const {BlockStatement, ContinueStatement} = types;
const buildLog = template(`console.log('TYPE' + ' ' + 'NAME')`);
const buildLogEnter = template(`console.log('enter' + ' ' + 'NAME' + '(' + JSON.stringify(Array.from(arguments)) + ')')`);
const buildLogException = template(`console.log('TYPE' + ' ' + 'NAME' + ': ' + trace$error.message); throw trace$error`);
const buildTryCatch = template(`try {
BLOCK;
} catch(trace$error) {
CATCH;
} finally {
FINALLY;
}
`);
const JSON = 'JSON';
module.exports.include = () => [
'Function',
];
module.exports.fix = (path) => {
const name = getName(path);
const enterLog = buildLogEnter({
NAME: name,
JSON,
});
const exitLog = buildLogEvent(name, 'exit');
const errorLog = buildLogExceptionEvent(name, 'error');
const bodyPath = path.get('body');
replaceWith(bodyPath, BlockStatement([buildTryCatch({
BLOCK: path.node.body.body,
CATCH: errorLog,
FINALLY: exitLog,
})]));
bodyPath.node.body.unshift(enterLog);
};
function getName(path) {
if (path.isClassMethod())
return path.node.key.name;
if (path.isFunctionDeclaration())
return path.node.id.name;
const {line} = path.node.loc.start;
return `<anonymous:${line}>`;
}
function buildLogEvent(name, type) {
return buildLog({
NAME: name,
TYPE: type,
});
}
function buildLogExceptionEvent(name, type) {
return buildLogException({
NAME: name,
TYPE: type,
});
}
Also I don't think you should log arguments
in events
other then enter
. Here is how it looks like:
from putout.
When I use this:
const putout = require('putout')
const source = { code: 'function X() { console.log("me") }' }
console.log(putout(source.code, {
plugins: [
['trace', require('./trace')],
]
}).code)
the codemod is a bit too enthusiastic, outputting this:
function X() {
console.log('enter' + ' ' + 'X' + '(' + JSON.stringify(Array.from(arguments)) + ')');
try {
console.log('enter' + ' ' + 'X' + '(' + JSON.stringify(Array.from(arguments)) + ')');
try {
console.log("me")
} catch (trace$error) {
console.log('error' + ' ' + 'X' + ': ' + trace$error.message);
throw trace$error;
} finally {
console.log('exit' + ' ' + 'X');
}
} catch (trace$error) {
console.log('error' + ' ' + 'X' + ': ' + trace$error.message);
throw trace$error;
} finally {
console.log('exit' + ' ' + 'X');
}
}
from putout.
By default, fix count is 2, so it should be set explicitly:
const putout = require('putout')
const source = { code: 'function X() { console.log("me") }' }
console.log(putout(source.code, {
fixCount: 1,
plugins: [
['trace', require('./trace')],
]
}).code)
Or checked with filter
function:
module.exports.filter = (path) => {
// check that body doesnβt contain enter event with help of require(βputoutβ).compare
}
@putout/compare gives ability to compare node
with string
.
from putout.
What does fixCount
do, conceptually? What are the downsides of setting it to 1
vs the default 2
?
from putout.
The codemode changes
$patch$(Zotero.Items, "merge", (original) => async function Zotero_Items_merge(item, otherItems) {
into
$patch$(Zotero.Items, "merge", original => {
(full function attached)
[post.js.txt](https://github.com/coderaiser/putout/files/6596879/post.js.txt)
[pre.js.txt](https://github.com/coderaiser/putout/files/6596880/pre.js.txt)
from putout.
What does fixCount do, conceptually? What are the downsides of setting it to 1 vs the default 2?
After first round of fixes, putout
checks again, because new places can occur and be fixed later. eslint
has 10 rounds of fixes by default :).
About removing arrow function
, we should probably change includes
back to traverse
:
module.exports.traverse = ({push}) => ({
Function(path) {
const bodyPath = path.get('body');
if (!bodyPath.isBlockStatement())
return;
if (isTryStatement(bodyPath.node.body[1]))
return;
push(path);
}
});
Here is full code:
const {template, types, operator} = require('putout');
const {replaceWith} = operator;
const {isTryStatement, BlockStatement, ContinueStatement} = types;
const buildLog = template(`console.log('TYPE' + ' ' + 'NAME')`);
const buildLogEnter = template(`console.log('enter' + ' ' + 'NAME' + '(' + JSON.stringify(Array.from(arguments)) + ')')`);
const buildLogException = template(`console.log('TYPE' + ' ' + 'NAME' + ': ' + trace$error.message); throw trace$error`);
const buildTryCatch = template(`try {
BLOCK;
} catch(trace$error) {
CATCH;
} finally {
FINALLY;
}
`);
const JSON = 'JSON';
module.exports.report = () => 'Log events should be used';
module.exports.traverse = ({push}) => ({
Function(path) {
const bodyPath = path.get('body');
if (!bodyPath.isBlockStatement())
return;
if (isTryStatement(bodyPath.node.body[1]))
return;
push(path);
}
});
module.exports.fix = (path) => {
const name = getName(path);
const enterLog = buildLogEnter({
NAME: name,
JSON,
});
const exitLog = buildLogEvent(name, 'exit');
const errorLog = buildLogExceptionEvent(name, 'error');
const bodyPath = path.get('body');
replaceWith(bodyPath, BlockStatement([buildTryCatch({
BLOCK: path.node.body.body,
CATCH: errorLog,
FINALLY: exitLog,
})]));
bodyPath.node.body.unshift(enterLog);
};
function getName(path) {
if (path.isClassMethod())
return path.node.key.name;
if (path.isFunctionDeclaration())
return path.node.id.name;
const {line} = path.node.loc.start;
return `<anonymous:${line}>`;
}
function buildLogEvent(name, type) {
return buildLog({
NAME: name,
TYPE: type,
});
}
function buildLogExceptionEvent(name, type) {
return buildLogException({
NAME: name,
TYPE: type,
});
}
And better to write tests for such cases, because there can be a lot of them :)
from putout.
Super thanks for your help! This gets a lot further, but currently fails on https://gist.github.com/5733125ed09534820b39fcae0e544d80 with
Error: @babel/template placeholder "NAME": Expected string substitution
from putout.
Works like a charm!
This is awesome π!
Can I send data to the plugin? I'd like to add the filename in addition to the line number, and I understand I can add that as a FILENAME replacement on buildLogEnter etc, but I don't know how to get the value for FILENAME in. Or should I just declare module.exports.FILENAME and set that from outside the plugin (which works)?
There is no way to get file name from the plug-in, this is done to make things as much code-oriented and independent from file structure as possible (anyways plugins has options
argument which can in future contain file name), so declaring setFileName
is a good idea π‘
from putout.
I currently have a private copy of this putout plugin, but that's going to get stale quickly. Is there a way for me to re-use the code published in ESTrace? I've looked at the source but I think the templates have estrace-specific code.
from putout.
I currently have a private copy of this putout plugin, but that's going to get stale quickly. Is there a way for me to re-use the code published in ESTrace? I've looked at the source but I think the templates have estrace-specific code.
Yes, you can use ESTrace as plugin this way:
import putout from 'putout';
import estracePlugin from 'estrace/plugin';
const source = `
const fn = (a) => a;
`;
const {code} = putout(source, {
plugins: [
['estrace', estracePlugin],
],
});
console.log(code);
from putout.
That is for estrace -- my code runs in a Zotero plugin, not in node, and I apply the trace codemod using bundling with esbuild.js
. My current use of the codemod looks like this but I'd prefer to replace that as much as possible with something that I can get a maintained copy for through npm install
.
from putout.
You should update this part:
const trace = await import('estrace/plugin');
Also you should add aliases:
window.__estrace = {
enter(name, url, arguments) {
Zotero.debug(`enter ${name} ${url}.(${JSON.stringify(Array.from(arguments), trace$circularReplacer())})`);
},
exit(name, url, result) {
Zotero.debug(`exit ${name} ${url}`);
},
}
from putout.
But replacing that part would also replace the call to putout, and would mean I cannot specify the filename or the circular-safe replacer function.
from putout.
But replacing that part would also replace the call to putout, and would mean I cannot specify the filename or the circular-safe replacer function.
I'm talking about changing declaration of trace
variable using require
:
const trace = require('./trace');
to import
of estreace/plugin
:
const trace = await import('estrace/plugin');
from putout.
Ah OK, that link pointed to a few lines at once. But that'd still leave the problem with the circular replacer, and that I can't pass the file name. The second I could in principle do without, but I do have functions that accept objects with circular links.
from putout.
Just replacing that require
with the await import
yields:
> node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/is-enabled.js:4:23: error: [plugin: trace] Cannot convert object to primitive value
4 β const value = rules[name];
β΅ ^
at Array.join (<anonymous>)
at Array.toString (<anonymous>)
at module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/is-enabled.js:4:24)
at module.exports.loadPlugins (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/index.js:97:14)
at transform (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/putout/lib/putout.js:93:21)
at module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/putout/lib/putout.js:53:20)
at /Users/emile/github/better-bibtex/setup/loaders/index.js:179:43
at async callback (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:869:28)
at async handleRequest (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:652:30)
from putout.
and that I can't pass the file name. The second I could in principle do without, but I do have functions
You can with:
const tracer = await import('estrace/plugin');
const withFileName = {
...tracer,
FILENAME: 'hello.js',
};
Or pass it directly with help of rules
similar to the way ESTrace works:
const tracer = await import('estrace/plugin');
const {code} = putout(source, {
rules: {
trace: ['on', {
url,
}],
},
plugins: [
['tracer', tracer],
],
});
from putout.
Just replacing that require with the await import yields:
Looks like you have outdated version of [email protected]
, try to update to latest version.
But that'd still leave the problem with the circular replacer,
What circular replacer
is used for?
from putout.
Looks like you have outdated version of
[email protected]
, try to update to latest version.
My bad. Updated.
What
circular replacer
is used for?
If you have an object that links back to itself, the standard JSON.stringify will just chase those links to until it runs into a recursion error. The circular replacer cuts those links off after the first.
I see how to add them now, it's just like adding the aliases for __estrace.
from putout.
I currently have this:
const tracer = await import('estrace/plugin');
const {code} = putout(source.code, {
fixCount: 1,
rules: {
trace: ['on', { url: localpath.replace(/\.ts$/, '') }],
},
plugins: [
['tracer', tracer],
],
})
with putout 18.3.0 and I'm getting
> node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/validate-rules.js:23:18: error: [plugin: trace] no plugin found for a rule: "trace"
23 β throw Error(`no plugin found for a rule: "${rule}"`);
β΅ ^
at module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/validate-rules.js:23:19)
at module.exports.loadPlugins (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/index.js:84:5)
at transform (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/putout/lib/putout.js:93:21)
at module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/putout/lib/putout.js:53:20)
at /Users/emile/github/better-bibtex/setup/loaders/index.js:188:22
at async callback (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:869:28)
at async handleRequest (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:652:30)
from putout.
If I replace
trace: ['on', { url: localpath.replace(/\.ts$/, '') }],
with
tracer: ['on', { url: localpath.replace(/\.ts$/, '') }],
I get
> node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/is-enabled.js:4:23: error: [plugin: trace] Cannot convert object to primitive value
4 β const value = rules[name];
β΅ ^
at Array.join (<anonymous>)
at Array.toString (<anonymous>)
at module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/is-enabled.js:4:24)
at module.exports.loadPlugins (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/index.js:97:14)
at transform (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/putout/lib/putout.js:93:21)
at module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/putout/lib/putout.js:53:20)
at /Users/emile/github/better-bibtex/setup/loaders/index.js:188:22
at async callback (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:869:28)
at async handleRequest (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:652:30)
from putout.
The error happens in engine-loader/lib/is-enabled.js
, which reads:
module.exports = (name, rules) => {
const value = rules[name];
if (typeof value === 'boolean')
return value;
let resultState = true;
for (const {rule, state} of rules) {
if (RegExp(`^${rule}`).test(name))
resultState = state;
}
return resultState;
};
but I've inspected the input, what I see is:
name
= 'trace'
, and rules
is an array, not an object; this works without problem, but the second time it is called,
name
is an array, and rules
is an array,
and that yields the Cannot convert object to primitive value
error.
from putout.
The error happens in engine-loader/lib/is-enabled.js, which reads:
Just fixed with 20ce6b4 in @putout/engine-loader
. Please re-install putout
.
from putout.
Done, the errors are now
> node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:53:19: error: [plugin: trace] Cannot read property 'value' of undefined
53 β const ret = fn.call(this.state, this, this.state);
β΅ ^
at isSkip (file:///Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/estrace/lib/trace/plugin-trace/index.js:165:20)
at Function (file:///Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/estrace/lib/trace/plugin-trace/index.js:36:17)
at NodePath._call (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:53:20)
at NodePath.call (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:40:17)
at NodePath.visit (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:90:31)
at TraversalContext.visitQueue (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/context.js:99:16)
at TraversalContext.visitMultiple (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/context.js:68:17)
at TraversalContext.visit (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/context.js:125:19)
at Function.traverse.node (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/index.js:76:17)
at NodePath.visit (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:97:18)
and
> node_modules/.pnpm/@[email protected]/node_modules/@babel/template/lib/populate.js:62:12: error: [plugin: trace] @babel/template placeholder "NAME": Expected string substitution
62 β throw new Error("Expected string substitution");
β΅ ^
at applyReplacement (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/template/lib/populate.js:62:13)
at /Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/template/lib/populate.js:32:7
at Array.forEach (<anonymous>)
at populatePlaceholders (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/template/lib/populate.js:30:43)
at /Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/template/lib/string.js:20:51
at /Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/template/lib/builder.js:75:14
at addEnter (file:///Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/estrace/lib/trace/plugin-trace/index.js:100:19)
at fix (file:///Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/estrace/lib/trace/plugin-trace/index.js:55:5)
at module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/try-catch/lib/try-catch.js:5:23)
at tryToFix (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-runner/lib/run-fix.js:8:17)
=============
at /Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-parser/lib/template.js:18:16
at /Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/nano-memoize/index.js:84:37
at file:///Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/estrace/lib/trace/plugin-trace/index.js:17:20
at ModuleJob.run (node:internal/modules/esm/module_job:175:25)
at async Loader.import (node:internal/modules/esm/loader:178:24)
at async importModuleDynamicallyWrapper (node:internal/vm/module:437:15)
at async /Users/emile/github/better-bibtex/setup/loaders/index.js:186:22
at async callback (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:869:28)
from putout.
Done, the errors are now
> node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:53:19: error: [plugin: trace] Cannot read property 'value' of undefined 53 β const ret = fn.call(this.state, this, this.state); β΅ ^ at isSkip (file:///Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/estrace/lib/trace/plugin-trace/index.js:165:20) at Function (file:///Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/estrace/lib/trace/plugin-trace/index.js:36:17) at NodePath._call (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:53:20) at NodePath.call (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:40:17) at NodePath.visit (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:90:31) at TraversalContext.visitQueue (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/context.js:99:16) at TraversalContext.visitMultiple (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/context.js:68:17) at TraversalContext.visit (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/context.js:125:19) at Function.traverse.node (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/index.js:76:17) at NodePath.visit (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:97:18)
Looks like itβs related to comments. Could you please tell me what code can be the reason?
You can add:
if (!comment.value)
console.log(String(path));
from putout.
I've added if (!comment.value) console.log('NO COMMENT', String(path));
but it doesn't look like I'm hitting that path.
It looks like it's hitting the problem for https://gist.github.com/9c7cd0d3cf8b9ca534473c0c28a3440c. I can translate that to javascript if you prefer.
from putout.
I've added
if (!comment.value) console.log('NO COMMENT', String(path));
but it doesn't look like I'm hitting that path.It looks like it's hitting the problem for https://gist.github.com/9c7cd0d3cf8b9ca534473c0c28a3440c. I can translate that to javascript if you prefer.
It transformed with no problems
from putout.
This generates the error I put in the comment at the top:
https://gist.github.com/6da57992197dc38d2593f8b3a87b1520
compiled using
const putout = require('putout')
const fs = require('fs')
async function main() {
try {
const localpath = 'formatter.ts'
const tracer = await import('estrace/plugin');
const source = { code: fs.readFileSync('/tmp/formatter.js', 'utf-8') }
const { code } = putout(source.code, { fixCount: 1, rules: { tracer: ['on', { url: localpath.replace(/\.ts$/, '') }] }, plugins: [ ['tracer', tracer] ] })
}
catch (err) {
console.log(err)
}
}
main()
from putout.
This generates the error I put in the comment at the top:
Fixed with coderaiser/estrace@901a252. Landed in estrace v1.6.0 π .
Is it works for you?
from putout.
It gets past the previous error, but I'm hitting https://gist.github.com/69975f9fdfab6606577be925c2df5004
from putout.
Closed due to a long time of inactivity π.
from putout.
Related Issues (20)
- Incorrect order of initialization of variables HOT 4
- Incorrect removing of an expression HOT 2
- ignore test files HOT 5
- path is missing for ruler toggler HOT 2
- babel config is not loaded. HOT 13
- how to run just specific rules HOT 1
- putout ignores camelCased paths HOT 1
- Using async functions in replacer HOT 6
- Mistaken removal of semi from unnamed prop types in FC HOT 12
- @putout/printer: Removed useful comma in TS HOT 6
- π name.startsWith is not a function HOT 13
- How to use indetifier name as a string? HOT 4
- It it possible to use Putout as Eslint backend? HOT 1
- remove-unused-expressions: "use client" false warning HOT 2
- ESLint integration fail HOT 4
- Option to configure printer overrides from HOT 10
- doesn't work with yarn 4 and pnp HOT 2
- does more than asked for HOT 3
- Closing arrow bracket (>) inside React components should not be transformed into `>` automatically HOT 1
- `npm install` broken due to eslint shenanigans HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from putout.