coderaiser / putout

🐊 Pluggable and configurable JavaScript Linter, code transformer and formatter, drop-in ESLint superpower replacement 💪 with built-in support for js, jsx, typescript, flow, markdown, yaml and json. Write declarative codemods in a simplest possible way 😏
https://putout.cloudcmd.io/
MIT License
712 stars 40 forks source link

How to use indetifier name as a string? #209

Closed artalar closed 5 months ago

artalar commented 5 months ago

Hi there! Thanks you for this super powerful tool. Can you help me, how can I use an indetifier string representations as a string? If I wrap it to a quotes, it removes for some reason...

image

coderaiser commented 5 months ago

It is overwritten with __a which is Identifier, template variables cannot change it’s type, only environment they used in.

Here is how it can look like:

export const report = () => `Add argument to ‘reatomComponent`;

export const match = ({__a}) => ({
    'const __a = reatomComponent(__b)': ({__a}, path) => {
      return isIdentifier(__a);
    }
});

export const replace = () => ({
    'const __a = reatomComponent(__b)': ({__a}, path) => {
      return `const __a = reatomComponent(__b, '${__a.name}')`
    }
});

See in action:

And don’t forget that __a can also be ObjectPattern or ArrayPattern, you can filter them out with match().

Also redput can help you to generate tests for your codemod.

artalar commented 5 months ago

Awesome, thank you!

coderaiser commented 5 months ago

You can also use @putout/plugin-putout, it reports such cases:

image

And see this error inside 🐊Mobile Putout Editor

image
coderaiser commented 5 months ago

I have and idea, that can make such plugin even simpler:

export const report = () => `Add argument to 'reatomComponent'`;

export const replace = ({
    'const __identifier__a = atom(__b)': 'const __identifier__a = atom(__b, __extract(__identifier__a))',
}

In this case no matcher will be needed. @artalar What do you think about such syntax?

__extract is extract from @putout/operate.