Skip to content

Commit 84d2efc

Browse files
committedMar 7, 2018
Merge branch 'master' of https://github.com/facebook/jscodeshift
2 parents 11981ad + aada675 commit 84d2efc

14 files changed

+189
-29
lines changed
 

‎CODE_OF_CONDUCT.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Code of Conduct
2+
3+
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.

‎CONTRIBUTING.md

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
We want to make contributing to this project as easy and transparent as
33
possible.
44

5+
## Code of Conduct
6+
The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)
7+
58
## Our Development Process
69
The majority of development on jscodeshift will occur through GitHub. Accordingly,
710
the process for contributing will follow standard GitHub protocol.

‎README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ module.exports = function(fileInfo, api) {
100100
}
101101
```
102102

103-
**Note:** This api is exposed for convenience, but you don't have to use it.
103+
**Note:** This API is exposed for convenience, but you don't have to use it.
104104
You can use any tool to modify the source.
105105

106106
`stats` is a function that only works when the `--dry` options is set. It accepts
@@ -360,7 +360,7 @@ This will run two tests: One for `__testfixtures__/FirstFixture.input.js` and on
360360
#### `defineInlineTest`
361361
```js
362362
const transform = require('../myTransform');
363-
defineInlineTest(transform, {}, 'input', 'expected output');
363+
defineInlineTest(transform, {}, 'input', 'expected output', 'test name (optional)');
364364
```
365365

366366
### Example Codemods

‎package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,19 @@
2626
"author": "Felix Kling",
2727
"license": "BSD-3-Clause",
2828
"dependencies": {
29-
"async": "^1.5.0",
3029
"babel-plugin-transform-flow-strip-types": "^6.8.0",
3130
"babel-preset-es2015": "^6.9.0",
3231
"babel-preset-stage-1": "^6.5.0",
3332
"babel-register": "^6.9.0",
34-
"babylon": "^6.17.3",
33+
"babylon": "^7.0.0-beta.30",
3534
"colors": "^1.1.2",
3635
"flow-parser": "^0.*",
3736
"lodash": "^4.13.1",
3837
"micromatch": "^2.3.7",
38+
"neo-async": "^2.5.0",
3939
"node-dir": "0.1.8",
4040
"nomnom": "^1.8.1",
41-
"recast": "^0.12.5",
41+
"recast": "^0.14.1",
4242
"temp": "^0.8.1",
4343
"write-file-atomic": "^1.2.0"
4444
},

‎parser/babylon.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const options = {
3131
'asyncGenerators',
3232
'functionBind',
3333
'functionSent',
34+
'dynamicImport',
3435
],
3536
};
3637

‎sample/__tests__/reverse-identifiers-test.js

+5
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@ var droWtsrif = 'Hello ';
3333
var droWdnoces = 'world';
3434
var egassem = droWtsrif + droWdnoces;
3535
`);
36+
defineInlineTest(transform, {},
37+
'function aFunction() {};',
38+
'function noitcnuFa() {};',
39+
'Reverses function names'
40+
);
3641
});

‎src/Collection.js

+24
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,30 @@ class Collection {
7878
return this;
7979
}
8080

81+
/**
82+
* Tests whether at-least one path passes the test implemented by the provided callback.
83+
*
84+
* @param {function} callback
85+
* @return {boolean}
86+
*/
87+
some(callback) {
88+
return this.__paths.some(
89+
(path, i, paths) => callback.call(path, path, i, paths)
90+
);
91+
}
92+
93+
/**
94+
* Tests whether all paths pass the test implemented by the provided callback.
95+
*
96+
* @param {function} callback
97+
* @return {boolean}
98+
*/
99+
every(callback) {
100+
return this.__paths.every(
101+
(path, i, paths) => callback.call(path, path, i, paths)
102+
);
103+
}
104+
81105
/**
82106
* Executes the callback for every path in the collection and returns a new
83107
* collection from the return values (which must be paths).

‎src/Runner.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -157,17 +157,19 @@ function run(transformFile, paths, options) {
157157
})
158158
.on('end', () => {
159159
temp.open('jscodeshift', (err, info) => {
160-
reject(err);
161-
fs.write(info.fd, contents);
162-
fs.close(info.fd, function(err) {
163-
reject(err);
164-
transform(info.path).then(resolve, reject);
160+
if (err) return reject(err);
161+
fs.write(info.fd, contents, function (err) {
162+
if (err) return reject(err);
163+
fs.close(info.fd, function(err) {
164+
if (err) return reject(err);
165+
transform(info.path).then(resolve, reject);
166+
});
165167
});
166168
});
167169
})
168170
})
169171
.on('error', (e) => {
170-
reject(e.message);
172+
reject(e);
171173
});
172174
});
173175
} else if (!fs.existsSync(transformFile)) {

‎src/Worker.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
const EventEmitter = require('events').EventEmitter;
1414

15-
const async = require('async');
15+
const async = require('neo-async');
1616
const fs = require('fs');
1717
const writeFileAtomic = require('write-file-atomic');
1818
const getParser = require('./getParser');

‎src/__tests__/Collection-test.js

+40
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,46 @@ describe('Collection API', function() {
234234
});
235235
});
236236

237+
describe('some', function() {
238+
it('lets you test each element of a collection and stops when one passes the test', function() {
239+
const each = jest.genMockFunction().mockImplementation(() => true);
240+
Collection.fromNodes(nodes).some(each);
241+
242+
expect(each.mock.calls.length).toBe(1);
243+
expect(each.mock.calls[0][0].value).toBe(nodes[0]);
244+
});
245+
246+
it('returns true if at least one element passes the test', function() {
247+
const result = Collection.fromNodes(nodes).some((_, i) => i === 1);
248+
expect(result).toBe(true);
249+
});
250+
251+
it('returns false if no elements pass the test', function() {
252+
const result = Collection.fromNodes(nodes).some(() => false);
253+
expect(result).toBe(false);
254+
});
255+
});
256+
257+
describe('every', function() {
258+
it('lets you test each element of a collection and stops when one fails the test', function() {
259+
const each = jest.genMockFunction().mockImplementation(() => false);
260+
Collection.fromNodes(nodes).every(each);
261+
262+
expect(each.mock.calls.length).toBe(1);
263+
expect(each.mock.calls[0][0].value).toBe(nodes[0]);
264+
});
265+
266+
it('returns true if all elements pass the test', function() {
267+
const result = Collection.fromNodes(nodes).every(() => true);
268+
expect(result).toBe(true);
269+
});
270+
271+
it('returns false if at least one element does not pass the test', function() {
272+
const result = Collection.fromNodes(nodes).every((_, i) => i === 1);
273+
expect(result).toBe(false);
274+
});
275+
});
276+
237277
describe('map', function() {
238278
it('returns a new collection with mapped values', function() {
239279
const root = Collection.fromNodes(nodes);

‎src/collections/VariableDeclarator.js

+24
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,15 @@ const transformMethods = {
114114
return false;
115115
}
116116

117+
if (
118+
types.JSXAttribute.check(parent) &&
119+
parent.name === path.node &&
120+
!parent.computed
121+
) {
122+
// <Foo oldName={oldName} />
123+
return false;
124+
}
125+
117126
return true;
118127
})
119128
.forEach(function(path) {
@@ -125,6 +134,21 @@ const transformMethods = {
125134
scope = scope.parent;
126135
}
127136
if (scope) { // identifier must refer to declared variable
137+
138+
// It may look like we filtered out properties,
139+
// but the filter only ignored property "keys", not "value"s
140+
// In shorthand properties, "key" and "value" both have an
141+
// Identifier with the same structure.
142+
const parent = path.parent.node;
143+
if (
144+
types.Property.check(parent) &&
145+
parent.shorthand &&
146+
!parent.method
147+
) {
148+
149+
path.parent.get('shorthand').replace(false);
150+
}
151+
128152
path.get('name').replace(newName);
129153
}
130154
});

‎src/collections/__tests__/VariableDeclarator-test.js

+43
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ describe('VariableDeclarators', function() {
5353
' blah() {}',
5454
' }',
5555
'}',
56+
'<Component foo={foo} />',
5657
].join('\n'), {parser: getParser()}).program];
5758
});
5859

@@ -127,6 +128,48 @@ describe('VariableDeclarators', function() {
127128

128129
expect(identifiers.length).toBe(1);
129130
});
131+
132+
it('properly renames a shorthand property that was using the old variable name', function() {
133+
nodes = [recast.parse([
134+
'var foo = 42;',
135+
'var obj2 = {',
136+
' foo,',
137+
'};',
138+
].join('\n'), {parser: getParser()}).program];
139+
140+
// Outputs:
141+
// var newFoo = 42;
142+
// var obj2 = {
143+
// foo: newFoo,
144+
// };
145+
Collection.fromNodes(nodes)
146+
.findVariableDeclarators('foo').renameTo('newFoo');
147+
148+
expect(
149+
Collection.fromNodes(nodes).find(types.Identifier, { name: 'newFoo' }).length
150+
).toBe(2);
151+
expect(
152+
Collection.fromNodes(nodes).find(types.Identifier, { name: 'foo' }).length
153+
).toBe(1);
154+
155+
expect(
156+
Collection.fromNodes(nodes).find(types.Property).filter(prop => !prop.value.shorthand).length
157+
).toBe(1);
158+
expect(
159+
Collection.fromNodes(nodes).find(types.Property).filter(prop => prop.value.shorthand).length
160+
).toBe(0);
161+
});
162+
163+
it('does not rename React component prop name', function () {
164+
const declarators = Collection.fromNodes(nodes)
165+
.findVariableDeclarators('foo')
166+
.renameTo('xyz');
167+
168+
const identifiers = Collection.fromNodes(nodes)
169+
.find(types.JSXIdentifier, { name: 'foo' });
170+
171+
expect(identifiers.length).toBe(1);
172+
});
130173
});
131174

132175
});

‎src/testUtils.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ function defineTest(dirName, transformName, options, testFilePrefix) {
9393
}
9494
exports.defineTest = defineTest;
9595

96-
function defineInlineTest(module, options, input, expectedOutput) {
97-
it('transforms correctly', () => {
96+
function defineInlineTest(module, options, input, expectedOutput, testName) {
97+
it(testName || 'transforms correctly', () => {
9898
runInlineTest(module, options, {
9999
source: input
100100
}, expectedOutput);

‎yarn.lock

+30-15
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ assert-plus@^0.2.0:
129129
version "0.2.0"
130130
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
131131

132-
ast-types@0.9.11:
133-
version "0.9.11"
134-
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.11.tgz#371177bb59232ff5ceaa1d09ee5cad705b1a5aa9"
132+
ast-types@0.11.1:
133+
version "0.11.1"
134+
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.1.tgz#5bb3a8d5ba292c3f4ae94d46df37afc30300b990"
135135

136-
async@^1.4.0, async@^1.5.0:
136+
async@^1.4.0:
137137
version "1.5.2"
138138
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
139139

@@ -772,10 +772,14 @@ babel-types@^6.0.19, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24
772772
lodash "^4.2.0"
773773
to-fast-properties "^1.0.1"
774774

775-
babylon@^6.0.18, babylon@^6.13.0, babylon@^6.17.2, babylon@^6.17.3:
775+
babylon@^6.0.18, babylon@^6.13.0, babylon@^6.17.2:
776776
version "6.17.3"
777777
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.3.tgz#1327d709950b558f204e5352587fd0290f8d8e48"
778778

779+
babylon@^7.0.0-beta.30:
780+
version "7.0.0-beta.40"
781+
resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.40.tgz#91fc8cd56d5eb98b28e6fde41045f2957779940a"
782+
779783
balanced-match@^1.0.0:
780784
version "1.0.0"
781785
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@@ -980,7 +984,7 @@ convert-source-map@^1.1.0:
980984
version "1.5.0"
981985
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
982986

983-
core-js@^2.4.0, core-js@^2.4.1:
987+
core-js@^2.4.0:
984988
version "2.4.1"
985989
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
986990

@@ -1225,14 +1229,18 @@ esprima@^2.7.1:
12251229
version "2.7.3"
12261230
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
12271231

1228-
esprima@^3.1.1, esprima@~3.1.0:
1232+
esprima@^3.1.1:
12291233
version "3.1.3"
12301234
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
12311235

12321236
esprima@~3.0.0:
12331237
version "3.0.0"
12341238
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9"
12351239

1240+
esprima@~4.0.0:
1241+
version "4.0.0"
1242+
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
1243+
12361244
esquery@^1.0.0:
12371245
version "1.0.0"
12381246
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa"
@@ -2296,6 +2304,10 @@ natural-compare@^1.4.0:
22962304
version "1.4.0"
22972305
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
22982306

2307+
neo-async@^2.5.0:
2308+
version "2.5.0"
2309+
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f"
2310+
22992311
node-dir@0.1.8:
23002312
version "0.1.8"
23012313
resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d"
@@ -2556,15 +2568,14 @@ readline2@^1.0.1:
25562568
is-fullwidth-code-point "^1.0.0"
25572569
mute-stream "0.0.5"
25582570

2559-
recast@^0.12.5:
2560-
version "0.12.5"
2561-
resolved "https://registry.yarnpkg.com/recast/-/recast-0.12.5.tgz#1f21a04f0ffd8dea35c222492ffcfe3201c1e977"
2571+
recast@^0.14.1:
2572+
version "0.14.1"
2573+
resolved "https://registry.yarnpkg.com/recast/-/recast-0.14.1.tgz#959ea20d7cb970bea1ec059325b8bdaf0738b788"
25622574
dependencies:
2563-
ast-types "0.9.11"
2564-
core-js "^2.4.1"
2565-
esprima "~3.1.0"
2575+
ast-types "0.11.1"
2576+
esprima "~4.0.0"
25662577
private "~0.1.5"
2567-
source-map "~0.5.0"
2578+
source-map "~0.6.1"
25682579

25692580
rechoir@^0.6.2:
25702581
version "0.6.2"
@@ -2801,7 +2812,7 @@ source-map@^0.4.4:
28012812
dependencies:
28022813
amdefine ">=0.0.4"
28032814

2804-
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1:
2815+
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1:
28052816
version "0.5.6"
28062817
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
28072818

@@ -2811,6 +2822,10 @@ source-map@~0.2.0:
28112822
dependencies:
28122823
amdefine ">=0.0.4"
28132824

2825+
source-map@~0.6.1:
2826+
version "0.6.1"
2827+
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
2828+
28142829
spdx-correct@~1.0.0:
28152830
version "1.0.2"
28162831
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"

0 commit comments

Comments
 (0)
Please sign in to comment.