Git Product home page Git Product logo

Comments (45)

coderaiser avatar coderaiser commented on September 28, 2024 2

Just landed ESTrace based on our talk πŸŽ‰ .

from putout.

retorquere avatar retorquere commented on September 28, 2024 1

Also I don't think you should log arguments in events other then enter. Here is how it looks like:

I was working towards that... baby steps :)

from putout.

retorquere avatar retorquere commented on September 28, 2024 1

This is super awesome. I've never had this level of detail in my logging.

from putout.

coderaiser avatar coderaiser commented on September 28, 2024 1

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.

retorquere avatar retorquere commented on September 28, 2024 1

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.

retorquere avatar retorquere commented on September 28, 2024 1

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.

coderaiser avatar coderaiser commented on September 28, 2024 1

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.

retorquere avatar retorquere commented on September 28, 2024 1

Yep, works perfectly! Really needed this for a bug I'm trying to diagnose right now, thanks!

from putout.

retorquere avatar retorquere commented on September 28, 2024 1

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.

coderaiser avatar coderaiser commented on September 28, 2024

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:
image

from putout.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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 and exit 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>';
}

It works this way:
image

from putout.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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:
image

from putout.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

What does fixCount do, conceptually? What are the downsides of setting it to 1 vs the default 2?

from putout.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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,
    });
}

It will look this way:
image

And better to write tests for such cases, because there can be a lot of them :)

from putout.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

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.

retorquere avatar retorquere commented on September 28, 2024

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.

coderaiser avatar coderaiser commented on September 28, 2024

This generates the error I put in the comment at the top:

https://gist.github.com/6da57992197dc38d2593f8b3a87b1520

Fixed with coderaiser/estrace@901a252. Landed in estrace v1.6.0 πŸŽ‰ .

Is it works for you?

from putout.

retorquere avatar retorquere commented on September 28, 2024

It gets past the previous error, but I'm hitting https://gist.github.com/69975f9fdfab6606577be925c2df5004

from putout.

coderaiser avatar coderaiser commented on September 28, 2024

Closed due to a long time of inactivity 🏝.

from putout.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.