[jscodeshift] Fix lint violations in test/js-transforms

This commit is contained in:
Brie
2019-01-28 20:16:25 -08:00
parent 17c8595115
commit 60cec9121e
5 changed files with 40 additions and 37 deletions
@@ -10,14 +10,14 @@
*/
import { Transform, MemberExpression } from "jscodeshift";
const transform: Transform = function (file, api) {
const transform: Transform = (file, api) => {
const j = api.jscodeshift;
return j(file.source)
// Find stuff that looks like this.xyz.bind(this)
.find(j.CallExpression, {callee: {object: {object: j.ThisExpression}, property: {name: 'bind'}}})
// Ensure that .bind() is being called with only one argument, and that argument is "this".
.filter(p => p.value.arguments.length == 1 && p.value.arguments[0].type == "ThisExpression")
.filter(p => p.value.arguments.length === 1 && p.value.arguments[0].type === "ThisExpression")
// We can now replace it with ::this.xyz
.replaceWith(p => j.bindExpression(null, (p.value.callee as MemberExpression).object))
.toSource();
};
};
@@ -1,4 +1,5 @@
/** Converts
/**
* Converts
* onClick(function(a, b) {
* return a + b;
* }.bind(this),
@@ -13,7 +14,7 @@
*
* var a = function(c) { return c; }.bind(this);
*
** to
* to
* onClick((a, b) => a + b,
* (b, c) => 1);
*
@@ -27,27 +28,27 @@
*/
import { Transform, MemberExpression, FunctionExpression } from "jscodeshift";
const transform: Transform = function(file, api) {
const transform: Transform = (file, api) => {
const j = api.jscodeshift;
return j(file.source)
// We're looking for a CallExpression that's calling .bind() onto a FunctionExpression.
.find(j.CallExpression, {callee: {property: {name: 'bind'}, object: {type: 'FunctionExpression'}}})
// Verify that .bind() is only being called with `this` as it's sole arguments.
.filter(p => p.value.arguments.length == 1 && p.value.arguments[0].type == "ThisExpression")
.filter(p => p.value.arguments.length === 1 && p.value.arguments[0].type === "ThisExpression")
.replaceWith(p => {
var callee = p.value.callee as MemberExpression;
var object = callee.object as FunctionExpression;
const callee = p.value.callee as MemberExpression;
const object = callee.object as FunctionExpression;
// Grab the function body. Since we looked for the CallExpression originally, the "callee.object" would refer
// to the FunctionExpression that's being called .bind(this) on. We need the body of that function
// to transform into an ArrowFunctionExpression.
var body = object.body;
let body = object.body;
// We can get a bit clever here. If we have a function that consists of a single return statement in it's body,
// we can transform it to the more compact arrowFunctionExpression (a, b) => a + b, vs (a + b) => { return a + b }
var useExpression = false;
if (body.type == 'BlockStatement' && body.body.length == 1) {
let useExpression = false;
if (body.type === 'BlockStatement' && body.body.length === 1) {
const first = body.body[0];
if (first.type == "ReturnStatement") {
if (first.type === "ReturnStatement") {
useExpression = true;
body = first.argument!;
}
@@ -56,4 +57,4 @@ const transform: Transform = function(file, api) {
return j.arrowFunctionExpression(object.params, body, useExpression);
})
.toSource();
};
};
@@ -13,7 +13,7 @@
* var a = function(a, b) {
* return a + b + this.c;
* }
**
*
* var a = (a, b) => a + b
*
* var b = (a, b) => {
@@ -27,22 +27,22 @@
*/
import { Transform } from "jscodeshift";
const transform: Transform = function (file, api) {
const transform: Transform = (file, api) => {
const j = api.jscodeshift;
return j(file.source)
.find(j.FunctionExpression)
// We check for this expression, as if it's in a function expression, we don't want to re-bind "this" by
// using the arrowFunctionExpression. As that could potentially have some unintended consequences.
.filter(p => j(p).find(j.ThisExpression).size() == 0)
.filter(p => j(p).find(j.ThisExpression).size() === 0)
.replaceWith(p => {
var body = p.value.body;
let body = p.value.body;
// We can get a bit clever here. If we have a function that consists of a single return statement in it's body,
// we can transform it to the more compact arrowFunctionExpression (a, b) => a + b, vs (a + b) => { return a + b }
var useExpression = false;
if (body.type == 'BlockStatement' && body.body.length == 1) {
let useExpression = false;
if (body.type === 'BlockStatement' && body.body.length === 1) {
const first = body.body[0];
if (first.type == "ReturnStatement") {
if (first.type === "ReturnStatement") {
useExpression = true;
body = first.argument!;
}
@@ -5,7 +5,8 @@
* return <div foo={this.props.foo} bar={this.props.bar} />
* }
* }
*** To:
*
* To:
*
* class C extends React.Component() {
* render() {
@@ -21,14 +22,15 @@
*/
import { Transform, VariableDeclarator, ObjectPattern, Identifier, BlockStatement } from "jscodeshift";
// tslint:disable-next-line max-line-length
const keywordsStr = 'this function if return var else for new in typeof while case break try catch delete throw switch continue default instanceof do void finally with debugger implements interface package private protected public static class enum export extends import super true false null abstract boolean byte char const double final float goto int long native short synchronized throws transient volatile';
let keywords = keywordsStr.split(' ').reduce<{ [key: string]: boolean }>((f, k) => {
const keywords = keywordsStr.split(' ').reduce<{ [key: string]: boolean }>((f, k) => {
f[k] = true;
return f;
}, {});
const isKeyword = (k: string) => keywords.hasOwnProperty(k);
const transform: Transform = function (file, api) {
const transform: Transform = (file, api) => {
const j = api.jscodeshift;
const {statement} = j.template;
@@ -50,15 +52,15 @@ const transform: Transform = function (file, api) {
const node: VariableDeclarator = decl.nodes()[0];
if (!(node.init != null &&
node.init.type == 'MemberExpression' &&
node.init.object.type == 'ThisExpression' &&
node.init.property.type == 'Identifier' &&
node.init.property.name == 'props'))
node.init.type === 'MemberExpression' &&
node.init.object.type === 'ThisExpression' &&
node.init.property.type === 'Identifier' &&
node.init.property.name === 'props'))
return false;
// Check for the case where it could be aliased (i.e.) { baz: foo } = this.props;
// In this case, we won't do a substitution.
if (p.parentPath.value.type == 'Property' && p.parentPath.value.key.name !== name)
if (p.parentPath.value.type === 'Property' && p.parentPath.value.key.name !== name)
return false;
return true;
@@ -81,10 +83,10 @@ const transform: Transform = function (file, api) {
// If the scope is null, that means that this property isn't defined in the scope yet,
// and we can use it. Otherwise, if it is defined, we should see if it was defined from `this.props`
// if none of these cases are true, we can't do substitution.
return resolvedScope == null || isFromProps((e.value.property as Identifier).name, resolvedScope);
return resolvedScope === null || isFromProps((e.value.property as Identifier).name, resolvedScope);
})
// Ensure that our substitution won't cause us to define a keyword, i.e. `this.props.while` won't
// get converted into `while`.
// get converted into `while`.
.filter(p => !isKeyword((p.value.property as Identifier).name))
// Now, do the replacement, `this.props.xyz` => `xyz`.
.replaceWith(p => p.value.property as Identifier)
@@ -96,7 +98,6 @@ const transform: Transform = function (file, api) {
variablesToReplace[p.value.name] = true;
});
// Create property definitions for variables that we've replaced.
const properties = Object.keys(variablesToReplace)
.sort()
@@ -1,5 +1,6 @@
/** For when you've gone too pure and want to go back. **/
/** Converts
/** For when you've gone too pure and want to go back. */
/**
* Converts
* let HistoryItem = (props) => {
* const {
* item
@@ -29,7 +30,7 @@
import { Transform, ASTNode } from "jscodeshift";
const transform: Transform = function (file, api) {
const transform: Transform = (file, api) => {
const j = api.jscodeshift;
const {statement} = j.template;
@@ -39,7 +40,7 @@ const transform: Transform = function (file, api) {
return j(file.source)
.find(j.VariableDeclaration)
.filter(p => p.value.declarations.length == 1)
.filter(p => p.value.declarations.length === 1)
.replaceWith(p => {
const decl = p.value.declarations[0];
if (decl.type === "VariableDeclarator" && decl.init != null) {
@@ -48,7 +49,7 @@ const transform: Transform = function (file, api) {
return p.value;
let body: any = decl.init.body;
body = body.type == "JSXElement" ? j.returnStatement(body) : body = body.body;
body = body.type === "JSXElement" ? j.returnStatement(body) : body = body.body;
j(body)
.find(j.Identifier, {name: 'props'})