Skip to content

Commit

Permalink
Merge pull request facebook#102 from acdlite/createclassdisplayname
Browse files Browse the repository at this point in the history
Update the createClass transform to insert a display name
  • Loading branch information
acdlite authored Mar 30, 2017
2 parents b5ecba1 + 41f0f91 commit b3f6079
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 28 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"eslint": "^2.13.1",
"fbjs-scripts": "^0.7.1",
"jest": "^17.0.3",
"jscodeshift": "^0.3.30"
"jscodeshift": "^0.3.30",
"path": "^0.12.7"
},
"jest": {
"globals": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ const React = require('react');
const createReactClass__deprecated = require('createReactClass__deprecated');

const Component = createReactClass__deprecated({
displayName: 'Component',
mixins: [{}],

render() {
return <div />;
}
},
});
31 changes: 31 additions & 0 deletions transforms/__testfixtures__/class/class-displayName.input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const React = require('React');

let A = React.createClass({
mixins: [],
render() {
return <div />;
},
});

A = React.createClass({
mixins: [],
render() {
return <div />;
},
});

const obj = {
B: React.createClass({
mixins: [],
render() {
return <div />;
},
}),
};

export default React.createClass({
mixins: [],
render() {
return <div />;
},
});
41 changes: 41 additions & 0 deletions transforms/__testfixtures__/class/class-displayName.output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const React = require('React');

const createReactClass = require('react-create-class');

let A = createReactClass({
displayName: 'A',
mixins: [],

render() {
return <div />;
},
});

A = createReactClass({
displayName: 'A',
mixins: [],

render() {
return <div />;
},
});

const obj = {
B: createReactClass({
displayName: 'B',
mixins: [],

render() {
return <div />;
},
}),
};

export default createReactClass({
displayName: 'class-displayName.input',
mixins: [],

render() {
return <div />;
},
});
12 changes: 8 additions & 4 deletions transforms/__testfixtures__/class/class-initial-state.input.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ var DeferStateInitialization = React.createClass({

var helper = () => {};

var PassGetInitialState = React.createClass({ // bail out here
// fallback
var PassGetInitialState = React.createClass({
getInitialState() {
return this.lol();
},
Expand All @@ -213,7 +214,8 @@ var PassGetInitialState = React.createClass({ // bail out here
},
});

var UseGetInitialState = React.createClass({ // bail out here
// fallback
var UseGetInitialState = React.createClass({
getInitialState() {
return this.lol();
},
Expand All @@ -227,7 +229,8 @@ var UseGetInitialState = React.createClass({ // bail out here
},
});

var UseArguments = React.createClass({ // bail out here
// fallback
var UseArguments = React.createClass({
helper() {
console.log(arguments);
},
Expand All @@ -237,7 +240,8 @@ var UseArguments = React.createClass({ // bail out here
},
});

var ShadowingIssue = React.createClass({ // bail out here
// fallback
var ShadowingIssue = React.createClass({
getInitialState() {
const props = { x: 123 };
return { x: props.x };
Expand Down
20 changes: 16 additions & 4 deletions transforms/__testfixtures__/class/class-initial-state.output.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,10 @@ class DeferStateInitialization extends React.Component {

var helper = () => {};

var PassGetInitialState = createReactClass({ // bail out here
// fallback
var PassGetInitialState = createReactClass({
displayName: 'PassGetInitialState',

getInitialState() {
return this.lol();
},
Expand All @@ -239,7 +242,10 @@ var PassGetInitialState = createReactClass({ // bail out here
},
});

var UseGetInitialState = createReactClass({ // bail out here
// fallback
var UseGetInitialState = createReactClass({
displayName: 'UseGetInitialState',

getInitialState() {
return this.lol();
},
Expand All @@ -253,7 +259,10 @@ var UseGetInitialState = createReactClass({ // bail out here
},
});

var UseArguments = createReactClass({ // bail out here
// fallback
var UseArguments = createReactClass({
displayName: 'UseArguments',

helper() {
console.log(arguments);
},
Expand All @@ -263,7 +272,10 @@ var UseArguments = createReactClass({ // bail out here
},
});

var ShadowingIssue = createReactClass({ // bail out here
// fallback
var ShadowingIssue = createReactClass({
displayName: 'ShadowingIssue',

getInitialState() {
const props = { x: 123 };
return { x: props.x };
Expand Down
2 changes: 2 additions & 0 deletions transforms/__testfixtures__/class/class-prune-react.output.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ const SomeMixin = {
};

export default createReactClass({
displayName: 'class-prune-react.input',
mixins: [SomeMixin],

render: function() {
return null;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ const SomeMixin = {
};

export default createReactClass({
displayName: 'class-prune-react2.input',
mixins: [SomeMixin],

render: function() {
return <div />;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ const SomeMixin = {
};

export default createReactClass({
displayName: 'class-prune-react3.input',
mixins: [SomeMixin],

propTypes: {
foo: PropTypes.string,
},

render: function() {
return null;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var createReactClass = require('react-create-class');
var ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');

var ComponentWithOnlyPureRenderMixin = createReactClass({
displayName: 'ComponentWithOnlyPureRenderMixin',
mixins: [ReactComponentWithPureRenderMixin],

getInitialState: function() {
Expand Down
2 changes: 2 additions & 0 deletions transforms/__testfixtures__/class/class-test2.output.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ module.exports = class extends React.Component {
};

var ComponentWithInconvertibleMixins = createReactClass({
displayName: 'ComponentWithInconvertibleMixins',
mixins: [ReactComponentWithPureRenderMixin, FooBarMixin],

getInitialState: function() {
Expand All @@ -68,6 +69,7 @@ var ComponentWithInconvertibleMixins = createReactClass({
var listOfInconvertibleMixins = [ReactComponentWithPureRenderMixin, FooBarMixin];

var ComponentWithInconvertibleMixins2 = createReactClass({
displayName: 'ComponentWithInconvertibleMixins2',
mixins: listOfInconvertibleMixins,

getInitialState: function() {
Expand Down
1 change: 1 addition & 0 deletions transforms/__testfixtures__/class/class.output.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class MyComponent3 extends React.Component {
}

var MyComponent4 = createReactClass({
displayName: 'MyComponent4',
foo: callMeMaybe(),
render: function() {},
});
Expand Down
1 change: 1 addition & 0 deletions transforms/__tests__/class-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ defineTest(__dirname, 'class', {
'create-class-module-name': 'createReactClass__deprecated',
'create-class-variable-name': 'createReactClass__deprecated',
}, 'class/class-create-class-naming');
defineTest(__dirname, 'class', null, 'class/class-displayName');
61 changes: 57 additions & 4 deletions transforms/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

'use strict';

const { basename, extname, dirname } = require('path');

module.exports = (file, api, options) => {
const j = api.jscodeshift;

Expand Down Expand Up @@ -1083,14 +1085,65 @@ module.exports = (file, api, options) => {
);
};

const addDisplayName = (displayName, specPath) => {
const props = specPath.properties;
let safe = true;

for (let i = 0; i < props.length; i++) {
const prop = props[i];
if (prop.key.name === 'displayName') {
safe = false;
break;
}
}

if (safe) {
props.unshift(j.objectProperty(j.identifier('displayName'), j.stringLiteral(displayName)));
}
};

const fallbackToCreateClassModule = (classPath) => {
const comments = getComments(classPath);
const specPath = ReactUtils.directlyGetCreateClassSpec(classPath);

if (specPath) {
// Add a displayName property to the spec object
let path = classPath;
let displayName;
while (path && displayName === undefined) {
switch (path.node.type) {
case 'ExportDefaultDeclaration':
displayName = basename(file.path, extname(file.path));
if (displayName === 'index') {
// ./{module name}/index.js
displayName = basename(dirname(file.path));
}
break;
case 'VariableDeclarator':
displayName = path.node.id.name;
break;
case 'AssignmentExpression':
displayName = path.node.left.name;
break;
case 'Property':
displayName = path.node.key.name;
break;
case 'Statement':
displayName = null;
break;
}
path = path.parent;
}
if (displayName) {
addDisplayName(displayName, specPath);
}
}

withComments(
j(classPath).replaceWith(
j.callExpression(
j.identifier(CREATE_CLASS_VARIABLE_NAME),
classPath.value.arguments
)
specPath
? j.callExpression(j.identifier(CREATE_CLASS_VARIABLE_NAME), [specPath])
: j.callExpression(j.identifier(CREATE_CLASS_VARIABLE_NAME), classPath.value.arguments)
),
{comments},
);
Expand Down
Loading

0 comments on commit b3f6079

Please sign in to comment.