Comparing version 0.4.24 to 0.5.0
# buble changelog | ||
## 0.5.0 | ||
* Support `--target`, `--yes` and `--no` in CLI | ||
* Compile entire directory of files via CLI | ||
* Sourcemap support in CLI | ||
* All transforms can be disabled (or errors suppressed) with the `transforms` option (or `--yes` and `--no`, in the CLI) | ||
* `import` and `export` will throw an error unless `--no modules` transform is specified | ||
* Fix bug with destructuring | ||
* Fix bug with block scoping and loops | ||
## 0.4.24 | ||
@@ -4,0 +15,0 @@ |
{ | ||
"name": "buble", | ||
"version": "0.4.24", | ||
"version": "0.5.0", | ||
"description": "The blazing fast, batteries-included ES2015 compiler", | ||
@@ -47,3 +47,5 @@ "main": "dist/buble.umd.js", | ||
"eslint": "^2.6.0", | ||
"glob": "^7.0.3", | ||
"mocha": "^2.4.5", | ||
"rimraf": "^2.5.2", | ||
"rollup": "^0.25.8", | ||
@@ -58,4 +60,6 @@ "rollup-plugin-buble": "^0.4.0", | ||
"acorn": "^3.0.4", | ||
"magic-string": "^0.11.2" | ||
"magic-string": "^0.11.2", | ||
"minimist": "^1.2.0", | ||
"rw": "^1.3.2" | ||
} | ||
} |
@@ -47,2 +47,8 @@ import { parse } from 'acorn'; | ||
Object.keys( options.transforms || {} ).forEach( name => { | ||
if ( name === 'modules' ) { | ||
if ( !( 'moduleImport' in options.transforms ) ) transforms.moduleImport = options.transforms.modules; | ||
if ( !( 'moduleExport' in options.transforms ) ) transforms.moduleExport = options.transforms.modules; | ||
return; | ||
} | ||
if ( !( name in transforms ) ) throw new Error( `Unknown transform '${name}'` ); | ||
@@ -49,0 +55,0 @@ transforms[ name ] = options.transforms[ name ]; |
@@ -105,111 +105,115 @@ import wrap from './wrap.js'; | ||
// object pattern | ||
params.filter( param => param.type === 'ObjectPattern' ).forEach( param => { | ||
const ref = this.scope.createIdentifier( 'ref' ); | ||
code.insert( param.start, ref ); | ||
if ( transforms.parameterDestructuring ) { | ||
params.filter( param => param.type === 'ObjectPattern' ).forEach( param => { | ||
const ref = this.scope.createIdentifier( 'ref' ); | ||
code.insert( param.start, ref ); | ||
let lastIndex = param.start; | ||
let lastIndex = param.start; | ||
param.properties.forEach( prop => { | ||
code.remove( lastIndex, prop.value.start ); | ||
param.properties.forEach( prop => { | ||
code.remove( lastIndex, prop.value.start ); | ||
if ( addedStuff ) code.insert( start, `\n${indentation}` ); | ||
if ( addedStuff ) code.insert( start, `\n${indentation}` ); | ||
const key = prop.key.name; | ||
const key = prop.key.name; | ||
if ( prop.value.type === 'Identifier' ) { | ||
code.remove( prop.value.start, prop.value.end ); | ||
lastIndex = prop.value.end; | ||
if ( prop.value.type === 'Identifier' ) { | ||
code.remove( prop.value.start, prop.value.end ); | ||
lastIndex = prop.value.end; | ||
const value = prop.value.name; | ||
code.insert( start, `var ${value} = ${ref}.${key};` ); | ||
} else if ( prop.value.type === 'AssignmentPattern' ) { | ||
code.remove( prop.value.start, prop.value.right.start ); | ||
lastIndex = prop.value.right.end; | ||
const value = prop.value.name; | ||
code.insert( start, `var ${value} = ${ref}.${key};` ); | ||
} else if ( prop.value.type === 'AssignmentPattern' ) { | ||
code.remove( prop.value.start, prop.value.right.start ); | ||
lastIndex = prop.value.right.end; | ||
const value = prop.value.left.name; | ||
code | ||
.insert( start, `var ${ref}_${key} = ref.${key}, ${value} = ref_${key} === void 0 ? ` ) | ||
.move( prop.value.right.start, prop.value.right.end, start ) | ||
.insert( start, ` : ref_${key};` ); | ||
} | ||
const value = prop.value.left.name; | ||
code | ||
.insert( start, `var ${ref}_${key} = ref.${key}, ${value} = ref_${key} === void 0 ? ` ) | ||
.move( prop.value.right.start, prop.value.right.end, start ) | ||
.insert( start, ` : ref_${key};` ); | ||
} | ||
else { | ||
throw new CompileError( prop, `Compound destructuring is not supported` ); | ||
} | ||
else { | ||
throw new CompileError( prop, `Compound destructuring is not supported` ); | ||
} | ||
addedStuff = true; | ||
lastIndex = prop.end; | ||
addedStuff = true; | ||
lastIndex = prop.end; | ||
}); | ||
code.remove( lastIndex, param.end ); | ||
}); | ||
code.remove( lastIndex, param.end ); | ||
}); | ||
// array pattern. TODO dry this out | ||
params.filter( param => param.type === 'ArrayPattern' ).forEach( param => { | ||
const ref = this.scope.createIdentifier( 'ref' ); | ||
code.insert( param.start, ref ); | ||
// array pattern. TODO dry this out | ||
params.filter( param => param.type === 'ArrayPattern' ).forEach( param => { | ||
const ref = this.scope.createIdentifier( 'ref' ); | ||
code.insert( param.start, ref ); | ||
let lastIndex = param.start; | ||
let lastIndex = param.start; | ||
param.elements.forEach( ( element, i ) => { | ||
code.remove( lastIndex, element.start ); | ||
param.elements.forEach( ( element, i ) => { | ||
code.remove( lastIndex, element.start ); | ||
if ( addedStuff ) code.insert( start, `\n${indentation}` ); | ||
if ( addedStuff ) code.insert( start, `\n${indentation}` ); | ||
if ( element.type === 'Identifier' ) { | ||
code.remove( element.start, element.end ); | ||
lastIndex = element.end; | ||
if ( element.type === 'Identifier' ) { | ||
code.remove( element.start, element.end ); | ||
lastIndex = element.end; | ||
code.insert( start, `var ${element.name} = ${ref}[${i}];` ); | ||
} else if ( element.type === 'AssignmentPattern' ) { | ||
code.remove( element.start, element.right.start ); | ||
lastIndex = element.right.end; | ||
code.insert( start, `var ${element.name} = ${ref}[${i}];` ); | ||
} else if ( element.type === 'AssignmentPattern' ) { | ||
code.remove( element.start, element.right.start ); | ||
lastIndex = element.right.end; | ||
const name = element.left.name; | ||
code | ||
.insert( start, `var ${ref}_${i} = ref[${i}], ${name} = ref_${i} === void 0 ? ` ) | ||
.move( element.right.start, element.right.end, start ) | ||
.insert( start, ` : ref_${i};` ); | ||
} | ||
const name = element.left.name; | ||
code | ||
.insert( start, `var ${ref}_${i} = ref[${i}], ${name} = ref_${i} === void 0 ? ` ) | ||
.move( element.right.start, element.right.end, start ) | ||
.insert( start, ` : ref_${i};` ); | ||
} | ||
else { | ||
throw new CompileError( element, `Compound destructuring is not supported` ); | ||
} | ||
else { | ||
throw new CompileError( element, `Compound destructuring is not supported` ); | ||
} | ||
addedStuff = true; | ||
lastIndex = element.end; | ||
}); | ||
addedStuff = true; | ||
lastIndex = element.end; | ||
code.remove( lastIndex, param.end ); | ||
}); | ||
} | ||
code.remove( lastIndex, param.end ); | ||
}); | ||
// rest parameter | ||
const lastParam = params[ params.length - 1 ]; | ||
if ( lastParam && lastParam.type === 'RestElement' ) { | ||
const penultimateParam = params[ params.length - 2 ]; | ||
if ( transforms.spreadRest ) { | ||
const lastParam = params[ params.length - 1 ]; | ||
if ( lastParam && lastParam.type === 'RestElement' ) { | ||
const penultimateParam = params[ params.length - 2 ]; | ||
if ( penultimateParam ) { | ||
code.remove( penultimateParam ? penultimateParam.end : lastParam.start, lastParam.end ); | ||
} else { | ||
let start = lastParam.start, end = lastParam.end; // TODO https://gitlab.com/Rich-Harris/buble/issues/8 | ||
if ( penultimateParam ) { | ||
code.remove( penultimateParam ? penultimateParam.end : lastParam.start, lastParam.end ); | ||
} else { | ||
let start = lastParam.start, end = lastParam.end; // TODO https://gitlab.com/Rich-Harris/buble/issues/8 | ||
while ( /\s/.test( code.original[ start - 1 ] ) ) start -= 1; | ||
while ( /\s/.test( code.original[ end ] ) ) end += 1; | ||
while ( /\s/.test( code.original[ start - 1 ] ) ) start -= 1; | ||
while ( /\s/.test( code.original[ end ] ) ) end += 1; | ||
code.remove( start, end ); | ||
} | ||
code.remove( start, end ); | ||
} | ||
if ( addedStuff ) code.insert( start, `\n${indentation}` ); | ||
if ( addedStuff ) code.insert( start, `\n${indentation}` ); | ||
const name = lastParam.argument.name; | ||
const len = this.scope.createIdentifier( 'len' ); | ||
const count = params.length - 1; | ||
const name = lastParam.argument.name; | ||
const len = this.scope.createIdentifier( 'len' ); | ||
const count = params.length - 1; | ||
if ( count ) { | ||
code.insert( start, `var ${name} = [], ${len} = arguments.length - ${count};\n${indentation}while ( ${len}-- > 0 ) ${name}[ ${len} ] = arguments[ ${len} + ${count} ];` ); | ||
} else { | ||
code.insert( start, `var ${name} = [], ${len} = arguments.length;\n${indentation}while ( ${len}-- ) ${name}[ ${len} ] = arguments[ ${len} ];` ); | ||
if ( count ) { | ||
code.insert( start, `var ${name} = [], ${len} = arguments.length - ${count};\n${indentation}while ( ${len}-- > 0 ) ${name}[ ${len} ] = arguments[ ${len} + ${count} ];` ); | ||
} else { | ||
code.insert( start, `var ${name} = [], ${len} = arguments.length;\n${indentation}while ( ${len}-- ) ${name}[ ${len} ] = arguments[ ${len} ];` ); | ||
} | ||
addedStuff = true; | ||
} | ||
addedStuff = true; | ||
} | ||
@@ -234,5 +238,7 @@ } | ||
if ( forStatement.shouldRewriteAsFunction && forStatement.reassigned[ name ] ) { | ||
if ( forStatement.shouldRewriteAsFunction ) { | ||
const outerAlias = this.scope.createIdentifier( name ); | ||
const innerAlias = this.scope.createIdentifier( name ); | ||
const innerAlias = forStatement.reassigned[ name ] ? | ||
this.scope.createIdentifier( name ) : | ||
name; | ||
@@ -239,0 +245,0 @@ forStatement.aliases[ name ] = { |
@@ -19,4 +19,4 @@ import Node from '../Node.js'; | ||
if ( this.left.type === 'ArrayPattern' ) { | ||
throw new CompileError( this.left, 'Assigning to an array pattern is not currently supported' ); | ||
if ( /Pattern/.test( this.left.type ) ) { | ||
throw new CompileError( this.left, 'Destructuring assignments are not currently supported. Coming soon!' ); | ||
} | ||
@@ -23,0 +23,0 @@ |
@@ -87,5 +87,7 @@ import Node from '../Node.js'; | ||
code.insert( method.start, `${lhs} = function` + ( isAccessor ? '' : ' ' ) ); | ||
code.insert( method.start, `${lhs} = function` + ( method.value.generator ? '*' : '' ) + ( isAccessor ? '' : ' ' ) ); | ||
code.insert( method.end, ';' ); | ||
if ( method.value.generator ) code.remove( method.start, method.key.start ); | ||
// prevent function name shadowing an existing declaration | ||
@@ -92,0 +94,0 @@ if ( scope.contains( method.key.name ) ) { |
import Node from '../Node.js'; | ||
import CompileError from '../../utils/CompileError.js'; | ||
export default class ExportDefaultDeclaration extends Node { | ||
initialise ( transforms ) { | ||
if ( transforms.moduleExport ) throw new CompileError( this, 'export is not supported' ); | ||
super.initialise( transforms ); | ||
} | ||
transpile ( code, transforms ) { | ||
@@ -5,0 +11,0 @@ super.transpile( code, transforms ); |
@@ -6,4 +6,4 @@ import Node from '../Node.js'; | ||
initialise ( transforms ) { | ||
throw new CompileError( this, 'for...of statements are not supported' ); | ||
if ( transforms.forOf ) throw new CompileError( this, 'for...of statements are not supported' ); | ||
} | ||
} |
@@ -6,3 +6,3 @@ import Node from '../Node.js'; | ||
initialise ( transforms ) { | ||
if ( this.generator ) { | ||
if ( this.generator && transforms.generator ) { | ||
throw new CompileError( this, 'Generators are not supported' ); | ||
@@ -9,0 +9,0 @@ } |
@@ -6,3 +6,3 @@ import Node from '../Node.js'; | ||
initialise ( transforms ) { | ||
if ( this.generator ) { | ||
if ( this.generator && transforms.generator ) { | ||
throw new CompileError( this, 'Generators are not supported' ); | ||
@@ -9,0 +9,0 @@ } |
@@ -11,2 +11,3 @@ import ArrayExpression from './ArrayExpression.js'; | ||
import ExportDefaultDeclaration from './ExportDefaultDeclaration.js'; | ||
import ExportNamedDeclaration from './ExportNamedDeclaration.js'; | ||
import ForStatement from './ForStatement.js'; | ||
@@ -18,4 +19,5 @@ import ForInStatement from './ForInStatement.js'; | ||
import Identifier from './Identifier.js'; | ||
import ImportDeclaration from './ImportDeclaration.js'; | ||
import ImportDefaultSpecifier from './ImportDefaultSpecifier.js'; | ||
import ImportSpecifier from './ImportSpecifier.js'; | ||
import ImportDefaultSpecifier from './ImportDefaultSpecifier.js'; | ||
import Literal from './Literal.js'; | ||
@@ -46,2 +48,3 @@ import LoopStatement from './shared/LoopStatement.js'; | ||
DoWhileStatement: LoopStatement, | ||
ExportNamedDeclaration, | ||
ExportDefaultDeclaration, | ||
@@ -54,4 +57,5 @@ ForStatement, | ||
Identifier, | ||
ImportDeclaration, | ||
ImportDefaultSpecifier, | ||
ImportSpecifier, | ||
ImportDefaultSpecifier, | ||
Literal, | ||
@@ -58,0 +62,0 @@ MemberExpression, |
@@ -14,6 +14,6 @@ import Node from '../Node.js'; | ||
if ( this.regex ) { | ||
if ( /u/.test( this.regex.flags ) ) throw new CompileError( this, 'Regular expression unicode flag is not supported' ); | ||
if ( /y/.test( this.regex.flags ) ) throw new CompileError( this, 'Regular expression sticky flag is not supported' ); | ||
if ( transforms.unicodeRegExp && /u/.test( this.regex.flags ) ) throw new CompileError( this, 'Regular expression unicode flag is not supported' ); | ||
if ( transforms.stickyRegExp && /y/.test( this.regex.flags ) ) throw new CompileError( this, 'Regular expression sticky flag is not supported' ); | ||
} | ||
} | ||
} |
@@ -7,3 +7,3 @@ import Node from '../Node.js'; | ||
initialise ( transforms ) { | ||
if ( this.computed ) { | ||
if ( this.computed && transforms.computedProperty ) { | ||
throw new CompileError( this.key, 'Computed properties are not supported' ); | ||
@@ -16,7 +16,9 @@ } | ||
transpile ( code, transforms ) { | ||
if ( this.parent.type !== 'ObjectPattern' ) { | ||
if ( transforms.conciseMethodProperty && this.parent.type !== 'ObjectPattern' ) { | ||
if ( this.shorthand ) { | ||
code.insert( this.start, `${this.key.name}: ` ); | ||
} else if ( this.method ) { | ||
code.insert( this.key.end, `: function` ); | ||
const name = this.findScope( true ).createIdentifier( this.key.name ); | ||
if ( this.value.generator ) code.remove( this.start, this.key.start ); | ||
code.insert( this.key.end, `: function${this.value.generator ? '*' : ''} ${name}` ); | ||
} | ||
@@ -23,0 +25,0 @@ } |
@@ -19,23 +19,25 @@ import Node from '../../Node.js'; | ||
// see if any block-scoped declarations are referenced | ||
// inside function expressions | ||
const names = Object.keys( this.body.scope.declarations ); | ||
if ( transforms.letConst ) { | ||
// see if any block-scoped declarations are referenced | ||
// inside function expressions | ||
const names = Object.keys( this.body.scope.declarations ); | ||
let i = names.length; | ||
while ( i-- ) { | ||
const name = names[i]; | ||
const declaration = this.body.scope.declarations[ name ]; | ||
let i = names.length; | ||
while ( i-- ) { | ||
const name = names[i]; | ||
const declaration = this.body.scope.declarations[ name ]; | ||
let j = declaration.instances.length; | ||
while ( j-- ) { | ||
const instance = declaration.instances[j]; | ||
const nearestFunctionExpression = instance.findNearest( /Function/ ); | ||
let j = declaration.instances.length; | ||
while ( j-- ) { | ||
const instance = declaration.instances[j]; | ||
const nearestFunctionExpression = instance.findNearest( /Function/ ); | ||
if ( nearestFunctionExpression && nearestFunctionExpression.depth > this.depth ) { | ||
this.shouldRewriteAsFunction = true; | ||
break; | ||
if ( nearestFunctionExpression && nearestFunctionExpression.depth > this.depth ) { | ||
this.shouldRewriteAsFunction = true; | ||
break; | ||
} | ||
} | ||
if ( this.shouldRewriteAsFunction ) break; | ||
} | ||
if ( this.shouldRewriteAsFunction ) break; | ||
} | ||
@@ -45,3 +47,2 @@ } | ||
transpile ( code, transforms ) { | ||
if ( this.shouldRewriteAsFunction ) { | ||
@@ -48,0 +49,0 @@ const i0 = this.getIndentation(); |
@@ -6,4 +6,4 @@ import Node from '../Node.js'; | ||
initialise ( transforms ) { | ||
throw new CompileError( this.tag, 'Tagged template expressions are not supported' ); | ||
if ( transforms.templateString ) throw new CompileError( this.tag, 'Tagged template expressions are not supported' ); | ||
} | ||
} |
@@ -5,36 +5,38 @@ import Node from '../Node.js'; | ||
transpile ( code, transforms ) { | ||
code.remove( this.start, this.start + 1 ); | ||
code.remove( this.end - 1, this.end ); | ||
if ( transforms.templateString ) { | ||
code.remove( this.start, this.start + 1 ); | ||
code.remove( this.end - 1, this.end ); | ||
const ordered = this.expressions.concat( this.quasis ).sort( ( a, b ) => a.start - b.start ); | ||
const ordered = this.expressions.concat( this.quasis ).sort( ( a, b ) => a.start - b.start ); | ||
const parenthesise = this.parent.type !== 'AssignmentExpression' && | ||
this.parent.type !== 'VariableDeclarator' && | ||
( this.parent.type !== 'BinaryExpression' || this.parent.operator !== '+' ); | ||
const parenthesise = this.parent.type !== 'AssignmentExpression' && | ||
this.parent.type !== 'VariableDeclarator' && | ||
( this.parent.type !== 'BinaryExpression' || this.parent.operator !== '+' ); | ||
if ( parenthesise ) code.insert( this.start, '(' ); | ||
if ( parenthesise ) code.insert( this.start, '(' ); | ||
let lastIndex = this.start; | ||
let closeParenthesis = false; | ||
let lastIndex = this.start; | ||
let closeParenthesis = false; | ||
ordered.forEach( ( node, i ) => { | ||
if ( node.type === 'TemplateElement' ) { | ||
const stringified = JSON.stringify( node.value.cooked ); | ||
const replacement = ( closeParenthesis ? ')' : '' ) + ( ( node.tail && !node.value.cooked.length && i !== 0 ) ? '' : `${i ? ' + ' : ''}${stringified}` ); | ||
code.overwrite( lastIndex, node.end, replacement ); | ||
ordered.forEach( ( node, i ) => { | ||
if ( node.type === 'TemplateElement' ) { | ||
const stringified = JSON.stringify( node.value.cooked ); | ||
const replacement = ( closeParenthesis ? ')' : '' ) + ( ( node.tail && !node.value.cooked.length && i !== 0 ) ? '' : `${i ? ' + ' : ''}${stringified}` ); | ||
code.overwrite( lastIndex, node.end, replacement ); | ||
closeParenthesis = false; | ||
} else { | ||
const parenthesise = node.type !== 'Identifier'; // TODO other cases where it's safe | ||
const open = parenthesise ? ( i ? ' + (' : '(' ) : ' + '; | ||
closeParenthesis = false; | ||
} else { | ||
const parenthesise = node.type !== 'Identifier'; // TODO other cases where it's safe | ||
const open = parenthesise ? ( i ? ' + (' : '(' ) : ' + '; | ||
code.overwrite( lastIndex, node.start, open ); | ||
code.overwrite( lastIndex, node.start, open ); | ||
closeParenthesis = parenthesise; | ||
} | ||
closeParenthesis = parenthesise; | ||
} | ||
lastIndex = node.end; | ||
}); | ||
lastIndex = node.end; | ||
}); | ||
code.overwrite( lastIndex, this.end, parenthesise ? ')' : '' ); | ||
code.overwrite( lastIndex, this.end, parenthesise ? ')' : '' ); | ||
} | ||
@@ -41,0 +43,0 @@ super.transpile( code, transforms ); |
@@ -27,3 +27,3 @@ import Node from '../Node.js'; | ||
transpile ( code, transforms ) { | ||
if ( this.id.type !== 'Identifier' ) { | ||
if ( transforms.destructuring && this.id.type !== 'Identifier' ) { | ||
const simple = this.init.type === 'Identifier'; | ||
@@ -52,3 +52,3 @@ const name = simple ? this.init.name : this.findScope( true ).createIdentifier( 'ref' ); | ||
code.overwrite( lastIndex, property.start, `${first ? '' : ', '}` ); | ||
code.overwrite( lastIndex, id.start, `${first ? '' : ', '}` ); | ||
code.insert( id.end, ` = ${rhs}` ); | ||
@@ -55,0 +55,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1104429
64
10040
4
10
2
+ Addedminimist@^1.2.0
+ Addedrw@^1.3.2
+ Addedminimist@1.2.8(transitive)
+ Addedrw@1.3.3(transitive)