Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fixing Program/BlockStatement rewrites #100

Closed
wants to merge 3 commits into from

3 participants

@jimfleming
Owner

Fixes #90

There is one failing test I haven't figured out how to fix yet. We need to unwrap ExpressionStatements for the general case but here if we don't then we end up with two semicolons.

@coveralls

Coverage Status

Coverage decreased (-4.75%) when pulling e000c0d on jimfleming:block_statement into 358532a on rdio:master.

@coveralls

Coverage Status

Coverage decreased (-1.8%) when pulling 376b24a on jimfleming:block_statement into 358532a on rdio:master.

@jimfleming jimfleming referenced this pull request
Closed

v0.4.0 #110

@brettlangdon brettlangdon commented on the diff
tests/rewrite.js
@@ -40,7 +67,7 @@ describe('jsfmt.rewrite', function() {
// Inside of "BlockStatement" instead of "Program"
jsfmt.rewrite('function test() { var myA = 1, myB = 2; }', 'var a = c, b = d; -> var a = c; var b = d;')
- .toString().should.eql('function test() {\n var myA = 1;\n var myB = 2;\n}');
+ .toString().should.eql('function test() { var myA = 1;\nvar myB = 2; }');
@brettlangdon Owner

this doesn't seem exactly right:

function test() { var myA = 1, myB = 2; }

gets rewritten to:

function test() { var myA = 1;
var myB = 2; }

is this the actual expected? I would assume it shouldn't get the newline?

@jimfleming Owner

Hmm, yah. So, what happens now is that when rewriting it only mangles the matched expressions, without context. So only the matched expressions will be formatted, post-rewrite. It may make sense to explicitly re-format the entire output. What do you think?

@brettlangdon Owner

well, we do that now dont we with rewriting? it'll reformat unless you give --no-format?

@jimfleming Owner

Hmm, good point. So this is just the raw output from the rewrite before the formatting has been applied.

@brettlangdon Owner

which actually might be ok, since we dont intend on testing formatting here, we want to test rewrite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@brettlangdon brettlangdon commented on the diff
tests/rewrite.js
@@ -60,6 +87,6 @@ describe('jsfmt.rewrite', function() {
});
it('should rewrite AssignmentExpression', function() {
- jsfmt.rewrite('var test = 4;', 'var a = b -> a += b').toString().should.eql('test += 4;');
+ jsfmt.rewrite('var test = 4;', 'var a = b -> a += b').toString().should.eql('test += 4');
@brettlangdon Owner

why do we lose the semicolon? shouldn't that stay?

@jimfleming Owner

Same reason as above. Its only matching the inner-expression (the part we care about) not the statement (the part that owns the semicolon). This is related to the test-failure where it creates a semi-colon for the matched expression (due to its own local context) but there was already a semi-colon there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jimfleming
Owner

Unfortunately I haven't had the time to delve into this (I think its at least a day of work to sort it out). Some thoughts:

  • Maybe we don't need to unwrap ExpressionStatement? I feel like I tried this and it caused different problems but we have more tests now.
  • Maybe this is a more fundamental problem with how I'm doing the rewriting.
@jimfleming
Owner

Needs a rewrite.

@jimfleming jimfleming closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 56 additions and 20 deletions.
  1. +1 −1  Gruntfile.js
  2. +2 −17 lib/rewrite.js
  3. +29 −2 tests/rewrite.js
  4. +24 −0 tests/search.js
View
2  Gruntfile.js
@@ -11,7 +11,7 @@ module.exports = function(grunt) {
mochaTest: {
tests: {
options: {
- reporter: 'spec',
+ reporter: 'spec'
},
src: ['tests/**/*.js'],
},
View
19 lib/rewrite.js
@@ -53,19 +53,6 @@ function unwrapNode(node) {
return node;
}
-// Same as `unwrapNode` except that this ensures both nodes are in sync
-function unwrapNodes(a, b) {
-
- if (a.type == 'Program' && a.body.length == 1 && b.type == 'Program' && b.body.length == 1) {
- return unwrapNodes(a.body[0], b.body[0]);
-
- } else if (a.type == 'ExpressionStatement' && b.type == 'ExpressionStatement') {
- return unwrapNodes(a.expression, b.expression);
- }
-
- return [a, b];
-}
-
function matchPartial(wildcards, patterns, nodes) {
// Copy nodes so we don't affect the original.
nodes = nodes.slice();
@@ -250,10 +237,8 @@ exports.rewrite = function(js, rewriteRule) {
var pattern = esprima.parse(rewriteRuleParts[0], parseOptions);
var replacement = esprima.parse(rewriteRuleParts[1], parseOptions);
-
- var patternReplacement = unwrapNodes(pattern, replacement);
- pattern = patternReplacement[0];
- replacement = patternReplacement[1];
+ pattern = unwrapNode(pattern);
+ replacement = unwrapNode(replacement);
js = falafel(js, parseOptions, function(node) {
var wildcards = {};
View
31 tests/rewrite.js
@@ -8,6 +8,33 @@ var libPath = process.env.JSFMT_COV ? 'lib-cov' : 'lib';
var jsfmt = require('../' + libPath + '/index');
describe('jsfmt.rewrite', function() {
+
+ it('should test multiline BlockStatement rewrite' ,function() {
+ var js = ['var x=true;', 'var y=false;',
+ 'x=1, y=2, z=3;',
+ 'function f() {', '}',
+ 'function g() {', '}',
+ 'if (x)', 'f();',
+ 'x || f();',
+ 'if (x) {', 'f();',
+ '} else {', 'g();',
+ '}'].join('\n');
+
+ var result = ['var x=true;', 'var y=false;',
+ 'x = 1;',
+ 'y = 2;',
+ 'z = 3;',
+ 'function f() {', '}',
+ 'function g() {', '}',
+ 'if (x)', 'f();',
+ 'x || f();',
+ 'if (x) {', 'f();',
+ '} else {', 'g();',
+ '}'].join('\n');
+
+ jsfmt.rewrite(js, 'a,b,c; -> a;b;c;').toString().should.eql(result);
+ });
+
it('should test basic rewrite', function() {
jsfmt.rewrite('_.each(a, b)', '_.each(a, b) -> a.forEach(b)')
.toString().should.eql('a.forEach(b)');
@@ -40,7 +67,7 @@ describe('jsfmt.rewrite', function() {
// Inside of "BlockStatement" instead of "Program"
jsfmt.rewrite('function test() { var myA = 1, myB = 2; }', 'var a = c, b = d; -> var a = c; var b = d;')
- .toString().should.eql('function test() {\n var myA = 1;\n var myB = 2;\n}');
+ .toString().should.eql('function test() { var myA = 1;\nvar myB = 2; }');
@brettlangdon Owner

this doesn't seem exactly right:

function test() { var myA = 1, myB = 2; }

gets rewritten to:

function test() { var myA = 1;
var myB = 2; }

is this the actual expected? I would assume it shouldn't get the newline?

@jimfleming Owner

Hmm, yah. So, what happens now is that when rewriting it only mangles the matched expressions, without context. So only the matched expressions will be formatted, post-rewrite. It may make sense to explicitly re-format the entire output. What do you think?

@brettlangdon Owner

well, we do that now dont we with rewriting? it'll reformat unless you give --no-format?

@jimfleming Owner

Hmm, good point. So this is just the raw output from the rewrite before the formatting has been applied.

@brettlangdon Owner

which actually might be ok, since we dont intend on testing formatting here, we want to test rewrite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
});
it('should be able to rewrite FunctionDeclaration', function() {
@@ -60,6 +87,6 @@ describe('jsfmt.rewrite', function() {
});
it('should rewrite AssignmentExpression', function() {
- jsfmt.rewrite('var test = 4;', 'var a = b -> a += b').toString().should.eql('test += 4;');
+ jsfmt.rewrite('var test = 4;', 'var a = b -> a += b').toString().should.eql('test += 4');
@brettlangdon Owner

why do we lose the semicolon? shouldn't that stay?

@jimfleming Owner

Same reason as above. Its only matching the inner-expression (the part we care about) not the statement (the part that owns the semicolon). This is related to the test-failure where it creates a semi-colon for the matched expression (due to its own local context) but there was already a semi-colon there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
});
});
View
24 tests/search.js
@@ -14,6 +14,30 @@ describe('jsfmt.search', function() {
results[0].wildcards.b.name.should.eql('done');
});
+ it('should test multiline BlockStatement search' ,function() {
+ var js = ['var x=true;', 'var y=false;',
+ 'x=1, y=2, z=3;',
+ 'function f() {', '}',
+ 'function g() {', '}',
+ 'a=4, b=5, c=6;',
+ 'if (x)', 'f();',
+ 'x || f();',
+ 'if (x) {', 'f();',
+ '} else {', 'g();',
+ '}'].join('\n');
+
+ var results = jsfmt.search(js, 'a,b,c;');
+ results.length.should.equal(2);
+
+ should.exist(results[0].wildcards.a);
+ should.exist(results[0].wildcards.b);
+ should.exist(results[0].wildcards.c);
+
+ should.exist(results[1].wildcards.a);
+ should.exist(results[1].wildcards.b);
+ should.exist(results[1].wildcards.c);
+ });
+
it('should test basic searching with shebang', function() {
var results = jsfmt.search('#!/usr/bin/env node\nvar param1 = 1, done = function(){}; _.each(param1, done);', '_.each(a, b);');
results[0].wildcards.a.name.should.eql('param1');
Something went wrong with that request. Please try again.