Browse Source

automatic semicolon insertion (fixes #1004, #1009). fight me

legacy-quote-reserved-properties
Rich-Harris 8 years ago
parent
commit
be952fef12
  1. 6
      src/ast/Node.js
  2. 5
      src/ast/nodes/ExpressionStatement.js
  3. 15
      src/ast/nodes/VariableDeclaration.js
  4. 3
      test/function/adds-semicolons-if-necessary-b/_config.js
  5. 1
      test/function/adds-semicolons-if-necessary-b/foo.js
  6. 3
      test/function/adds-semicolons-if-necessary-b/main.js
  7. 3
      test/function/adds-semicolons-if-necessary/_config.js
  8. 3
      test/function/adds-semicolons-if-necessary/foo.js
  9. 7
      test/function/adds-semicolons-if-necessary/main.js

6
src/ast/Node.js

@ -66,6 +66,12 @@ export default class Node {
this.eachChild( child => child.initialise( this.scope || scope ) );
}
insertSemicolon ( code ) {
if ( code.original[ this.end - 1 ] !== ';' ) {
code.insertLeft( this.end, ';' );
}
}
locate () {
// useful for debugging
const location = getLocation( this.module.code, this.start );

5
src/ast/nodes/ExpressionStatement.js

@ -1,5 +1,8 @@
import Statement from './shared/Statement.js';
export default class ExpressionStatement extends Statement {
render ( code, es ) {
super.render( code, es );
if ( this.shouldInclude ) this.insertSemicolon( code );
}
}

15
src/ast/nodes/VariableDeclaration.js

@ -14,7 +14,7 @@ function getSeparator ( code, start ) {
return `;\n${lineStart}`;
}
const forStatement = /^For(?:Of|In)Statement/;
const forStatement = /^For(?:Of|In)?Statement/;
export default class VariableDeclaration extends Node {
initialise ( scope ) {
@ -92,9 +92,16 @@ export default class VariableDeclaration extends Node {
if ( treeshake && empty ) {
code.remove( this.leadingCommentStart || this.start, this.next || this.end );
} else if ( this.end > c ) {
const hasSemicolon = code.original[ this.end - 1 ] === ';';
code.overwrite( c, this.end, hasSemicolon ? ';' : '' );
} else {
// always include a semi-colon (https://github.com/rollup/rollup/pull/1013),
// unless it's a var declaration in a loop head
const needsSemicolon = !forStatement.test( this.parent.type );
if ( this.end > c ) {
code.overwrite( c, this.end, needsSemicolon ? ';' : '' );
} else if ( needsSemicolon ) {
this.insertSemicolon( code );
}
}
}
}

3
test/function/adds-semicolons-if-necessary-b/_config.js

@ -0,0 +1,3 @@
module.exports = {
description: 'adds semi-colons if necessary'
};

1
test/function/adds-semicolons-if-necessary-b/foo.js

@ -0,0 +1 @@
assert.ok( true )

3
test/function/adds-semicolons-if-necessary-b/main.js

@ -0,0 +1,3 @@
import './foo.js';
(function bar() {})();

3
test/function/adds-semicolons-if-necessary/_config.js

@ -0,0 +1,3 @@
module.exports = {
description: 'adds semi-colons if necessary'
};

3
test/function/adds-semicolons-if-necessary/foo.js

@ -0,0 +1,3 @@
export var foo = function () {
return 42;
}

7
test/function/adds-semicolons-if-necessary/main.js

@ -0,0 +1,7 @@
import { foo } from './foo.js';
(function bar() {
assert.ok( true );
})();
assert.equal( foo(), 42 );
Loading…
Cancel
Save