Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas committed Mar 3, 2015
0 parents commit c826118
Show file tree
Hide file tree
Showing 9 changed files with 694 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules/
49 changes: 49 additions & 0 deletions bin/5to6.js
@@ -0,0 +1,49 @@
#!/usr/bin/env node

var commander = require("commander");
var main = require('../src/index');
var colors = require('colors');

var program = new commander.Command('5to6');

program.option("-s, --sources <type>", "Sources to convert from ES5 to ES6 i.e. 5to6 -s src/js");
program.option("-v, --verbose", "Verbose mode");

var pkg = require("../package.json");
program.version(pkg.version);
program.parse(process.argv);

// Verify sources
var sources = program.sources;
var verbose = program.verbose;

if (!sources) {
return program.help();
}

// Check git binary
var exec = require('child_process').exec;
exec('which git', verifyGit);

function verifyGit(error, stdout, stderr) {

// Git not installed
if (!stdout) {
return console.warn("git must to be installed. In case want to revert changes, can use `git reset --hard`".red);
}

// Make sure HEAD is clean
exec('git diff', verifyWorkingCopyClean);

function verifyWorkingCopyClean(error, stdout, stderr) {

if (stdout) {
return console.warn("git working copy must be clean, otherwise doing `git revert` later (if any) will revert previously changed files as well, so please commit your changed files first...".red);
}

main(sources, {verbose: verbose});

}

}

39 changes: 39 additions & 0 deletions package.json
@@ -0,0 +1,39 @@
{
"name": "5to6",
"version": "0.0.1",
"description": "Convert (partial) ES5 to ES6",
"main": "src/index.js",
"bin": {
"5to6": "./bin/5to6.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@github.com:thomasloh/5to6.git"
},
"keywords": [
"5to6",
"es5",
"es6",
"convert",
"babel",
"javascript",
"recast"
],
"author": "thomasloh",
"license": "ISC",
"bugs": {
"url": "https://github.com/thomasloh/5to6/issues"
},
"homepage": "https://github.com/thomasloh/5to6",
"dependencies": {
"bluebird": "^2.9.13",
"colors": "^1.0.3",
"commander": "^2.6.0",
"glob": "^4.4.1",
"lodash": "^3.3.1",
"recast": "^0.10.1"
}
}
109 changes: 109 additions & 0 deletions src/index.js
@@ -0,0 +1,109 @@
var recast = require('recast');
var _ = require('lodash');
var n = recast.types.namedTypes;
var b = recast.types.builders;
var fs = require('fs');
var colors = require('colors');
var Promise = require('bluebird');

var middlewares = [
require('./modules/convert-require-stmt-to-import-stmt'),
require('./modules/strip-use-stricts'),
require('./modules/convert-module-dot-export-to-export-default.js'),
require('./modules/convert-fn-expr-in-obj-to-shorthand'),
require('./modules/convert-same-key-value-in-obj-expr-to-just-key')
];

/////////////
// Convert //
/////////////
function convert(pattern, opts) {

var verbose = opts.verbose;

var glob = require('glob');
var path = require('path');
var exec = Promise.promisify(require('child_process').exec);
var p = path.join(process.cwd(), pattern, "/**/*.+(jsx|js)");

if (verbose) {
console.log("File pattern to search: " + p);
}

var files = glob.sync(p);
// var converted = [];
// var notConverted = [];

if (!files) {
if (verbose) {
console.log("Error globbing files.".red);
}
return;
}

if (!files.length) {
if (verbose) {
console.log("No files to convert.".yellow);
}
}

Promise.all(files.map(function(file) {

return exec('git ls-files ' + file + ' --error-unmatch').then(function() {

// Read file and parse to ast
var code = fs.readFileSync(file, "utf-8");
var ast = recast.parse(code);

if (!code) {
if (verbose) {
console.log(file + " is empty or does not exist.".yellow);
}
return;
}

// Run through middlewares
ast.program.body = middlewares.reduce(function(body, m) {
return m(body);
}, ast.program.body);

// Write
fs.writeFileSync(file, _.trimLeft(recast.print(ast).code));

if (verbose) {
console.log((file + " is converted.").green);
}

})
.catch(function(e) {
if (verbose) {
console.log((file + " is not converted because it's not tracked by git.").red);
}
});

}))
.then(function() {

// Output
// if (converted.length) {
// console.log([
// "The following files are converted:",
// converted.map(function(s) {return " " + s}).join(',\n'),
// ""
// ].join('\n').green);
// }

// if (notConverted.length) {
// console.log([
// "The following files are not converted because they are not tracked by git:",
// notConverted.map(function(s) {return " " + s}).join(',\n'),
// ""
// ].join('\n').red);
// }

})

}


module.exports = convert;
78 changes: 78 additions & 0 deletions src/modules/convert-fn-expr-in-obj-to-shorthand.js
@@ -0,0 +1,78 @@
var assert = require('assert');
var recast = require('recast');
var _ = require('lodash');
var n = recast.types.namedTypes;
var b = recast.types.builders;

// {
// abc: function() {
// console.log('a')
// }
// }
// =>
// {
// abc() {
// console.log('a')
// }
// }

module.exports = function convertFnExprOfObjExprPropTo(body) {

var bod = body;

if (body.type === "BlockStatement") {
bod = body.body;
}

bod = bod.map(function(o) {

if (!o) {
return o;
}

if (o.body) {
o.body = convertFnExprOfObjExprPropTo(o.body);
return o;
}

if (o.init && o.init.type === "ObjectExpression") {
o.init.properties = convertFnExprOfObjExprPropTo(o.init.properties);
return o;
}

if (o.init && o.init.type === "CallExpression") {
o.init.arguments = convertFnExprOfObjExprPropTo(o.init.arguments);
return o;
}

if (o.declarations) {
o.declarations = convertFnExprOfObjExprPropTo(o.declarations);
return o;
}

if (o.properties) {
o.properties = convertFnExprOfObjExprPropTo(o.properties);
return o;
}

try {
n.Property.assert(o);
n.Identifier.assert(o.key);
n.FunctionExpression.assert(o.value);
} catch(e) {
return o;
}

o.method = true;

return o;

});

if (body.type === "BlockStatement") {
body.body = bod;
}

return body;

};
40 changes: 40 additions & 0 deletions src/modules/convert-module-dot-export-to-export-default.js
@@ -0,0 +1,40 @@
var assert = require('assert');
var recast = require('recast');
var _ = require('lodash');
var n = recast.types.namedTypes;
var b = recast.types.builders;

// module.exports = Component
// =>
// export default Component

module.exports = function convertModuleDotExportToExportDefault(body) {

return body.map(function(o) {

if (!o) {
return o;
}

try {
n.ExpressionStatement.assert(o);
n.AssignmentExpression.assert(o.expression);
assert(o.expression.operator === "=", "Must be equal op");
n.MemberExpression.assert(o.expression.left);
n.Identifier.assert(o.expression.left.object);
assert(o.expression.left.object.name === "module", "Must be 'module' name");
n.Identifier.assert(o.expression.left.property);
assert(o.expression.left.property.name === "exports", "Must be 'exports' name");
n.Identifier.assert(o.expression.right);
} catch(e) {
return o;
}

var Module = o.expression.right.name;
o = b.exportDeclaration(true, b.identifier(Module));

return o;

});

};

0 comments on commit c826118

Please sign in to comment.