Giter Club home page Giter Club logo

Comments (15)

coderaiser avatar coderaiser commented on June 4, 2024 1

Sweet! How can I use this from JS code? Right now I have created a codemods with the file remove-async-await.js

It will look this way:

const fs = require('fs')
const putout = require('putout');
const removeAsyncAwait = require('./codemods/remove-async-await');

const source = fs.readFileSync('node_modules/kuroshiro/src/core.js', 'utf-8');
const {code} = putout(source, {
    plugins: [
        ['remove-async-await', removeAsyncAwait],
    ]
});

console.log(code);

Is it works for you?

from putout.

retorquere avatar retorquere commented on June 4, 2024 1

Superb -- the promise unwrapper does the job and emove-nested-blocks does the rest.

File citeproc is generated, would be better to work with src directory and build this file after transformations.

I'm installing the node package, and that only has the generated file. I'll see if I can put together a replacer that strips them.

from putout.

retorquere avatar retorquere commented on June 4, 2024 1

Man, I'm dump. There's no need for me to strip citeproc -- the dead code elimination of the bundler I use does a better job than I did, automatically.

from putout.

coderaiser avatar coderaiser commented on June 4, 2024

Thank you for such a good question :). You can use such code mode:

module.exports.report = () => 'async should be striped from init method';

module.exports.fix = (path) => {
    path.node.async = false;
    
    path.traverse({
        AwaitExpression(path) {
            path.replaceWith(path.node.argument);
        }
    });
}

module.exports.traverse = ({push}) => ({
    ClassMethod(path) {
        const keyPath = path.get('key');
        
        if (!keyPath.isIdentifier({name: 'init'}))
            return false;
        
        if (!path.node.async)
            return false;
        
        push(path);
    }
});

It works this way (you can try it in putout editor):
image

To run this codemod it in your codebase use, create file remove-async-await.js in directory codemods and run:

putout --rulesdir codemods .

It will find all occurrences which can be fixed with:

putout --rulesdir codemods . --fix

If you want to disable all other putout rules first, use:

putout --disable-all .

It will create file .putout.json with all found built-in rules violations disabled.

Is it worked for you?

from putout.

retorquere avatar retorquere commented on June 4, 2024

Sweet! How can I use this from JS code? Right now I have created a codemods with the file remove-async-await.js, but when I run this:

const fs = require('fs')
const putout = require('putout');

const source = fs.readFileSync('node_modules/kuroshiro/src/core.js', 'utf-8')
console.log(putout(source, { plugins: [ 'remove-async-await' ] }).code)

I get

/Users/emile/github/better-bibtex/node_modules/.pnpm/@putout+engine-loader@4.1.1/node_modules/@putout/engine-loader/lib/load.js:24
        throw Error(`${bigFirst(type)} "${namespace}-${type}-${name}" could not be found!`);
        ^

Error: Plugin "putout-plugin-remove-async-await" could not be found!
    at /Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/load.js:24:15
    at loadPlugins (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/index.js:153:38)
    at module.exports.loadPlugins (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-loader/lib/index.js:79:21)
    at transform (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/putout/lib/putout.js:91:21)
    at module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/[email protected]/node_modules/putout/lib/putout.js:51:20)
    at Object.<anonymous> (/Users/emile/github/better-bibtex/tt.js:5:13)
    at Module._compile (node:internal/modules/cjs/loader:1092:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1121:10)
    at Module.load (node:internal/modules/cjs/loader:972:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)

from putout.

retorquere avatar retorquere commented on June 4, 2024

There's also two other transforms I'm trying to get going; 1st is to transform

     parse(str = "") {
       return new Promise((resolve, reject) => {
           if (str.trim() === "") return resolve([]);
             const result = this._analyzer.tokenize(str);
             for (let i = 0; i < result.length; i++) {
                 result[i].verbose = {};
                 delete result[i].word_type;
                 delete result[i].word_position;
             }
           resolve(result);
       });
     }

into

     parse(str = "") {
           if (str.trim() === "") return [];
             const result = this._analyzer.tokenize(str);
             for (let i = 0; i < result.length; i++) {
                 result[i].verbose = {};
                 delete result[i].word_type;
                 delete result[i].word_position;
             }
           return result;
     }

with the 2nd I have an object

var CSL = {
      PROCESSOR_VERSION: "1.4.59",
      debug: function(str) { // default debug function
        if ("undefined" === typeof console) {
            dump("CSL: " + str + "\n");
        } else {
            console.log("citeproc-js warning: " + str);
        }
    },

    toLocaleUpperCase(str) {
        var arr = this.tmp.lang_array;
        try {
            str = str.toLocaleUpperCase(arr);
        } catch (e) {
            str = str.toUpperCase();
        }
        return str;
    },

    LOCATOR_LABELS_REGEXP: new RegExp('.'),

    // many more attributes
}

where I want to remove a list of named attributes (eg toLocaleUpperCase) from the object, regardless of their type.

from putout.

coderaiser avatar coderaiser commented on June 4, 2024

Here is transform for new Promise, it uses getTemplateValues to get ArrowFunctionExpression from ReturnStatement:

const {operator, types} = require('putout');
const {replaceWith, getTemplateValues} = operator;
const {ReturnStatement} = types;

module.exports.report = () => 'Promise should be removed';

module.exports.fix = (path) => {
    const returnPath = path.get('body.body.0');
    const returnNode = returnPath.node;
    const {__a} = getTemplateValues(returnNode, 'return new Promise(__a)');
    
    const {body} = __a.body;
    const n = body.length - 1;
    body[n] = ReturnStatement(body[n].expression.arguments[0]);
    
    replaceWith(returnPath, __a.body);
}

module.exports.traverse = ({push}) => ({
    ClassMethod(path) {
        const keyPath = path.get('key');
        const isParse = keyPath.isIdentifier({
            name: 'parse',
        });
        
        if (isParse)
            push(path);
    }
});

It works this way:
image

Nested blocks can be removed with @putout/remove-nested-blocks.

About list of keys you want to remove it will look this way:

image

And here is the code:

const {operator, types} = require('putout');
const {replaceWith, getTemplateValues} = operator;
const {ReturnStatement} = types;

module.exports.report = () => 'toLocalUpperCase should be removed';

module.exports.fix = (path) => {
    path.remove();
}

module.exports.traverse = ({push}) => ({
    ObjectMethod(path) {
        const keyPath = path.get('key');
        const list = [
            'toLocaleUpperCase'
        ];
        
        for (const name of list) {
            if (keyPath.isIdentifier({name}))
                push(path);
        }
    }
});

So you will have 3 files in your codemods directory :).

Is it works for you?

from putout.

retorquere avatar retorquere commented on June 4, 2024

The first one works splendidly!

Here is transform for new Promise, it uses getTemplateValues to get ArrowFunctionExpression from ReturnStatement:

with this one I get

/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-runner/lib/run-fix.js:15
    throw e;
    ^

TypeError: Cannot read property 'body' of undefined
    at module.exports.fix (/Users/emile/github/better-bibtex/codemods/remove-promise-wrapper.js:12:24)
    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 module.exports (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-runner/lib/run-fix.js:24:5)
    at push (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/engine-runner/lib/merge-visitors.js:92:9)
    at ClassMethod (/Users/emile/github/better-bibtex/codemods/remove-promise-wrapper.js:27:13)
    at NodePath._call (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:55:20)
    at NodePath.call (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:42:17)
    at NodePath.visit (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/path/context.js:92:31)
    at TraversalContext.visitQueue (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@babel/traverse/lib/context.js:116:16) {
  loc: { line: 76, column: 4 }
}

About list of keys you want to remove it will look this way:

With this one I get

AssertionError [ERR_ASSERTION]: No tab width specified but encountered tabs in string
/>[	 ]+</g
    at Object.fromString (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/lines.js:580:22)
    at genericPrintNoParens (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/printer.js:693:28)
    at genericPrint (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/printer.js:123:30)
    at print (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/printer.js:77:15)
    at /Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/patcher.js:151:28
    at Array.forEach (<anonymous>)
    at /Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/patcher.js:139:18
    at print (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/printer.js:76:17)
    at /Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/printer.js:49:41
    at Object.printComments (/Users/emile/github/better-bibtex/node_modules/.pnpm/@[email protected]/node_modules/@putout/recast/lib/comments.js:281:22) {
  generatedMessage: false,
  code: 'ERR_ASSERTION',
  actual: false,
  expected: true,
  operator: '=='
}

getTemplateValues is going to be a big help.

from putout.

coderaiser avatar coderaiser commented on June 4, 2024

Could you please provide me examples of code that cause exception? Looks like this is not the code you provided before, because that one works good in putout editor. I think they differ in a minor case which anyways should be checked separately like a fixtures.

You can read more about modifying of AST in babel handbook.

from putout.

retorquere avatar retorquere commented on June 4, 2024

I tried to minimize the samples, but the code being modified is:

  • node_modules/kuroshiro-analyzer-kuromoji/src/index.js from kuroshiro-analyzer-kuromoji (applying "Promise should be removed")
  • node_modules/citeproc/citeproc_commonjs.js from the citeproc package (applying "toLocalUpperCase should be removed")

I'll dive into the babel handbook, thanks!

from putout.

coderaiser avatar coderaiser commented on June 4, 2024

Looks like reject should be converted to throw.

from putout.

retorquere avatar retorquere commented on June 4, 2024

That is a good point.

from putout.

coderaiser avatar coderaiser commented on June 4, 2024

File citeproc is generated, would be better to work with src directory and build this file after transformations.

By the way you can test codemods using @putout/test, it uses fixtures, and make testing edge cases very simple and pleasant task :).

from putout.

coderaiser avatar coderaiser commented on June 4, 2024

Here is simplified version for kuroshiro-analyzer-kuromoji/src/index.js with reject converted to throw.

Previous version of a plugin was Traverser, this one is Replacer.
You can find all supported plugin types in @putout/engine-runner.

const {operator, types} = require('putout');
const {replaceWith} = operator;
const {ReturnStatement, ThrowStatement} = types;

module.exports.report = () => 'Promise should be removed';

module.exports.replace = () => ({
    'return new Promise(__a)'({__a}, path) {
        replaceWith(path, __a.body);
        return path;
    },
    
    'reject(__a)': ({__a}, path) => {
        replaceWith(path.parentPath, ThrowStatement(__a));
        return path;
    },
    'resolve(__a)': ({__a}, path) => {
        replaceWith(path.parentPath, ReturnStatement(__a));
        return path;
    },
    'resolve()': '',
});

Don't forget to use @putout/plugin-remove-nested-blocks. Here is how it looks like in Putout Editor:

image

Also you can enable @putout/plugin-putout it will help you with writing codemod.

from putout.

coderaiser avatar coderaiser commented on June 4, 2024

Just landed promises/convert-new-promise-to-async 🎉 , thank you for inspiration :). Check it out how it easy to test codemod.

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.