Template Upload
This commit is contained in:
305
node_modules/buble/src/program/BlockStatement.js
generated
vendored
Normal file
305
node_modules/buble/src/program/BlockStatement.js
generated
vendored
Normal file
@ -0,0 +1,305 @@
|
||||
import wrap from './wrap.js';
|
||||
import Node from './Node.js';
|
||||
import Scope from './Scope.js';
|
||||
import CompileError from '../utils/CompileError.js';
|
||||
import destructure from '../utils/destructure.js';
|
||||
|
||||
function isUseStrict ( node ) {
|
||||
if ( !node ) return false;
|
||||
if ( node.type !== 'ExpressionStatement' ) return false;
|
||||
if ( node.expression.type !== 'Literal' ) return false;
|
||||
return node.expression.value === 'use strict';
|
||||
}
|
||||
|
||||
export default class BlockStatement extends Node {
|
||||
createScope () {
|
||||
this.parentIsFunction = /Function/.test( this.parent.type );
|
||||
this.isFunctionBlock = this.parentIsFunction || this.parent.type === 'Root';
|
||||
this.scope = new Scope({
|
||||
block: !this.isFunctionBlock,
|
||||
parent: this.parent.findScope( false )
|
||||
});
|
||||
|
||||
if ( this.parentIsFunction ) {
|
||||
this.parent.params.forEach( node => {
|
||||
this.scope.addDeclaration( node, 'param' );
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
initialise ( transforms ) {
|
||||
this.thisAlias = null;
|
||||
this.argumentsAlias = null;
|
||||
this.defaultParameters = [];
|
||||
|
||||
// normally the scope gets created here, during initialisation,
|
||||
// but in some cases (e.g. `for` statements), we need to create
|
||||
// the scope early, as it pertains to both the init block and
|
||||
// the body of the statement
|
||||
if ( !this.scope ) this.createScope();
|
||||
|
||||
this.body.forEach( node => node.initialise( transforms ) );
|
||||
|
||||
this.scope.consolidate();
|
||||
}
|
||||
|
||||
findLexicalBoundary () {
|
||||
if ( this.type === 'Program' ) return this;
|
||||
if ( /^Function/.test( this.parent.type ) ) return this;
|
||||
|
||||
return this.parent.findLexicalBoundary();
|
||||
}
|
||||
|
||||
findScope ( functionScope ) {
|
||||
if ( functionScope && !this.isFunctionBlock ) return this.parent.findScope( functionScope );
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
getArgumentsAlias () {
|
||||
if ( !this.argumentsAlias ) {
|
||||
this.argumentsAlias = this.scope.createIdentifier( 'arguments' );
|
||||
}
|
||||
|
||||
return this.argumentsAlias;
|
||||
}
|
||||
|
||||
getArgumentsArrayAlias () {
|
||||
if ( !this.argumentsArrayAlias ) {
|
||||
this.argumentsArrayAlias = this.scope.createIdentifier( 'argsArray' );
|
||||
}
|
||||
|
||||
return this.argumentsArrayAlias;
|
||||
}
|
||||
|
||||
getThisAlias () {
|
||||
if ( !this.thisAlias ) {
|
||||
this.thisAlias = this.scope.createIdentifier( 'this' );
|
||||
}
|
||||
|
||||
return this.thisAlias;
|
||||
}
|
||||
|
||||
getIndentation () {
|
||||
if ( this.indentation === undefined ) {
|
||||
const source = this.program.magicString.original;
|
||||
|
||||
const useOuter = this.synthetic || !this.body.length;
|
||||
let c = useOuter ? this.start : this.body[0].start;
|
||||
|
||||
while ( c && source[c] !== '\n' ) c -= 1;
|
||||
|
||||
this.indentation = '';
|
||||
|
||||
while ( true ) {
|
||||
c += 1;
|
||||
const char = source[c];
|
||||
|
||||
if ( char !== ' ' && char !== '\t' ) break;
|
||||
|
||||
this.indentation += char;
|
||||
}
|
||||
|
||||
const indentString = this.program.magicString.getIndentString();
|
||||
|
||||
// account for dedented class constructors
|
||||
let parent = this.parent;
|
||||
while ( parent ) {
|
||||
if ( parent.kind === 'constructor' && !parent.parent.parent.superClass ) {
|
||||
this.indentation = this.indentation.replace( indentString, '' );
|
||||
}
|
||||
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
if ( useOuter ) this.indentation += indentString;
|
||||
}
|
||||
|
||||
return this.indentation;
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
const indentation = this.getIndentation();
|
||||
|
||||
let introStatementGenerators = [];
|
||||
|
||||
if ( this.argumentsAlias ) {
|
||||
introStatementGenerators.push( ( start, prefix, suffix ) => {
|
||||
const assignment = `${prefix}var ${this.argumentsAlias} = arguments;${suffix}`;
|
||||
code.insertLeft( start, assignment );
|
||||
});
|
||||
}
|
||||
|
||||
if ( this.thisAlias ) {
|
||||
introStatementGenerators.push( ( start, prefix, suffix ) => {
|
||||
const assignment = `${prefix}var ${this.thisAlias} = this;${suffix}`;
|
||||
code.insertLeft( start, assignment );
|
||||
});
|
||||
}
|
||||
|
||||
if ( this.argumentsArrayAlias ) {
|
||||
introStatementGenerators.push( ( start, prefix, suffix ) => {
|
||||
const i = this.scope.createIdentifier( 'i' );
|
||||
const assignment = `${prefix}var ${i} = arguments.length, ${this.argumentsArrayAlias} = Array(${i});\n${indentation}while ( ${i}-- ) ${this.argumentsArrayAlias}[${i}] = arguments[${i}];${suffix}`;
|
||||
code.insertLeft( start, assignment );
|
||||
});
|
||||
}
|
||||
|
||||
if ( /Function/.test( this.parent.type ) ) {
|
||||
this.transpileParameters( code, transforms, indentation, introStatementGenerators );
|
||||
}
|
||||
|
||||
if ( transforms.letConst && this.isFunctionBlock ) {
|
||||
this.transpileBlockScopedIdentifiers( code );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
|
||||
if ( this.synthetic ) {
|
||||
if ( this.parent.type === 'ArrowFunctionExpression' ) {
|
||||
const expr = this.body[0];
|
||||
|
||||
if ( introStatementGenerators.length ) {
|
||||
code.insertLeft( this.start, `{` ).insertRight( this.end, `${this.parent.getIndentation()}}` );
|
||||
|
||||
code.insertRight( expr.start, `\n${indentation}return ` );
|
||||
code.insertLeft( expr.end, `;\n` );
|
||||
} else if ( transforms.arrow ) {
|
||||
code.insertRight( expr.start, `{ return ` );
|
||||
code.insertLeft( expr.end, `; }` );
|
||||
}
|
||||
}
|
||||
|
||||
else if ( introStatementGenerators.length ) {
|
||||
code.insertLeft( this.start, `{` ).insertRight( this.end, `}` );
|
||||
}
|
||||
}
|
||||
|
||||
let start;
|
||||
if ( isUseStrict( this.body[0] ) ) {
|
||||
start = this.body[0].end;
|
||||
} else if ( this.synthetic || this.parent.type === 'Root' ) {
|
||||
start = this.start;
|
||||
} else {
|
||||
start = this.start + 1;
|
||||
}
|
||||
|
||||
let prefix = `\n${indentation}`;
|
||||
let suffix = '';
|
||||
introStatementGenerators.forEach( ( fn, i ) => {
|
||||
if ( i === introStatementGenerators.length - 1 ) suffix = `\n`;
|
||||
fn( start, prefix, suffix );
|
||||
});
|
||||
}
|
||||
|
||||
transpileParameters ( code, transforms, indentation, introStatementGenerators ) {
|
||||
const params = this.parent.params;
|
||||
|
||||
params.forEach( param => {
|
||||
if ( param.type === 'AssignmentPattern' && param.left.type === 'Identifier' ) {
|
||||
if ( transforms.defaultParameter ) {
|
||||
introStatementGenerators.push( ( start, prefix, suffix ) => {
|
||||
const lhs = `${prefix}if ( ${param.left.name} === void 0 ) ${param.left.name}`;
|
||||
|
||||
code
|
||||
.insertRight( param.left.end, `${lhs}` )
|
||||
.move( param.left.end, param.right.end, start )
|
||||
.insertLeft( param.right.end, `;${suffix}` );
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
else if ( param.type === 'RestElement' ) {
|
||||
if ( transforms.spreadRest ) {
|
||||
introStatementGenerators.push( ( start, prefix, suffix ) => {
|
||||
const penultimateParam = params[ params.length - 2 ];
|
||||
|
||||
if ( penultimateParam ) {
|
||||
code.remove( penultimateParam ? penultimateParam.end : param.start, param.end );
|
||||
} else {
|
||||
let start = param.start, end = param.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;
|
||||
|
||||
code.remove( start, end );
|
||||
}
|
||||
|
||||
const name = param.argument.name;
|
||||
const len = this.scope.createIdentifier( 'len' );
|
||||
const count = params.length - 1;
|
||||
|
||||
if ( count ) {
|
||||
code.insertLeft( start, `${prefix}var ${name} = [], ${len} = arguments.length - ${count};\n${indentation}while ( ${len}-- > 0 ) ${name}[ ${len} ] = arguments[ ${len} + ${count} ];${suffix}` );
|
||||
} else {
|
||||
code.insertLeft( start, `${prefix}var ${name} = [], ${len} = arguments.length;\n${indentation}while ( ${len}-- ) ${name}[ ${len} ] = arguments[ ${len} ];${suffix}` );
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
else if ( param.type !== 'Identifier' ) {
|
||||
if ( transforms.parameterDestructuring ) {
|
||||
const ref = this.scope.createIdentifier( 'ref' );
|
||||
destructure( code, this.scope, param, ref, introStatementGenerators );
|
||||
code.insertLeft( param.start, ref );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
transpileBlockScopedIdentifiers ( code ) {
|
||||
Object.keys( this.scope.blockScopedDeclarations ).forEach( name => {
|
||||
const declarations = this.scope.blockScopedDeclarations[ name ];
|
||||
|
||||
for ( let declaration of declarations ) {
|
||||
let cont = false; // TODO implement proper continue...
|
||||
|
||||
if ( declaration.kind === 'for.let' ) {
|
||||
// special case
|
||||
const forStatement = declaration.node.findNearest( 'ForStatement' );
|
||||
|
||||
if ( forStatement.shouldRewriteAsFunction ) {
|
||||
const outerAlias = this.scope.createIdentifier( name );
|
||||
const innerAlias = forStatement.reassigned[ name ] ?
|
||||
this.scope.createIdentifier( name ) :
|
||||
name;
|
||||
|
||||
declaration.name = outerAlias;
|
||||
code.overwrite( declaration.node.start, declaration.node.end, outerAlias, true );
|
||||
|
||||
forStatement.aliases[ name ] = {
|
||||
outer: outerAlias,
|
||||
inner: innerAlias
|
||||
};
|
||||
|
||||
for ( const identifier of declaration.instances ) {
|
||||
const alias = forStatement.body.contains( identifier ) ?
|
||||
innerAlias :
|
||||
outerAlias;
|
||||
|
||||
if ( name !== alias ) {
|
||||
code.overwrite( identifier.start, identifier.end, alias, true );
|
||||
}
|
||||
}
|
||||
|
||||
cont = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !cont ) {
|
||||
const alias = this.scope.createIdentifier( name );
|
||||
|
||||
if ( name !== alias ) {
|
||||
declaration.name = alias;
|
||||
code.overwrite( declaration.node.start, declaration.node.end, alias, true );
|
||||
|
||||
for ( const identifier of declaration.instances ) {
|
||||
identifier.rewritten = true;
|
||||
code.overwrite( identifier.start, identifier.end, alias, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
108
node_modules/buble/src/program/Node.js
generated
vendored
Normal file
108
node_modules/buble/src/program/Node.js
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
import wrap from './wrap.js';
|
||||
import keys from './keys.js';
|
||||
|
||||
// used for debugging, without the noise created by
|
||||
// circular references
|
||||
function toJSON ( node ) {
|
||||
var obj = {};
|
||||
|
||||
Object.keys( node ).forEach( key => {
|
||||
if ( key === 'parent' || key === 'program' || key === 'keys' || key === '__wrapped' ) return;
|
||||
|
||||
if ( Array.isArray( node[ key ] ) ) {
|
||||
obj[ key ] = node[ key ].map( toJSON );
|
||||
} else if ( node[ key ] && node[ key ].toJSON ) {
|
||||
obj[ key ] = node[ key ].toJSON();
|
||||
} else {
|
||||
obj[ key ] = node[ key ];
|
||||
}
|
||||
});
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
export default class Node {
|
||||
constructor ( raw, parent ) {
|
||||
raw.parent = parent;
|
||||
raw.program = parent.program || parent;
|
||||
raw.depth = parent.depth + 1;
|
||||
raw.keys = keys[ raw.type ];
|
||||
raw.indentation = undefined;
|
||||
|
||||
for ( const key of keys[ raw.type ] ) {
|
||||
wrap( raw[ key ], raw );
|
||||
}
|
||||
|
||||
raw.program.magicString.addSourcemapLocation( raw.start );
|
||||
raw.program.magicString.addSourcemapLocation( raw.end );
|
||||
}
|
||||
|
||||
ancestor ( level ) {
|
||||
let node = this;
|
||||
while ( level-- ) {
|
||||
node = node.parent;
|
||||
if ( !node ) return null;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
contains ( node ) {
|
||||
while ( node ) {
|
||||
if ( node === this ) return true;
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
findLexicalBoundary () {
|
||||
return this.parent.findLexicalBoundary();
|
||||
}
|
||||
|
||||
findNearest ( type ) {
|
||||
if ( typeof type === 'string' ) type = new RegExp( `^${type}$` );
|
||||
if ( type.test( this.type ) ) return this;
|
||||
return this.parent.findNearest( type );
|
||||
}
|
||||
|
||||
findScope ( functionScope ) {
|
||||
return this.parent.findScope( functionScope );
|
||||
}
|
||||
|
||||
getIndentation () {
|
||||
return this.parent.getIndentation();
|
||||
}
|
||||
|
||||
initialise ( transforms ) {
|
||||
for ( var key of this.keys ) {
|
||||
const value = this[ key ];
|
||||
|
||||
if ( Array.isArray( value ) ) {
|
||||
value.forEach( node => node && node.initialise( transforms ) );
|
||||
} else if ( value && typeof value === 'object' ) {
|
||||
value.initialise( transforms );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return toJSON( this );
|
||||
}
|
||||
|
||||
toString () {
|
||||
return this.program.magicString.original.slice( this.start, this.end );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
for ( const key of this.keys ) {
|
||||
const value = this[ key ];
|
||||
|
||||
if ( Array.isArray( value ) ) {
|
||||
value.forEach( node => node && node.transpile( code, transforms ) );
|
||||
} else if ( value && typeof value === 'object' ) {
|
||||
value.transpile( code, transforms );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
53
node_modules/buble/src/program/Program.js
generated
vendored
Normal file
53
node_modules/buble/src/program/Program.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
import MagicString from 'magic-string';
|
||||
import BlockStatement from './BlockStatement.js';
|
||||
import wrap from './wrap.js';
|
||||
|
||||
export default function Program ( source, ast, transforms, options ) {
|
||||
this.type = 'Root';
|
||||
|
||||
// options
|
||||
this.jsx = options.jsx || 'React.createElement';
|
||||
this.objectAssign = options.objectAssign || 'Object.assign';
|
||||
|
||||
this.source = source;
|
||||
this.magicString = new MagicString( source );
|
||||
|
||||
this.ast = ast;
|
||||
this.depth = 0;
|
||||
|
||||
wrap( this.body = ast, this );
|
||||
this.body.__proto__ = BlockStatement.prototype;
|
||||
|
||||
this.templateElements = [];
|
||||
this.body.initialise( transforms );
|
||||
|
||||
this.indentExclusions = {};
|
||||
for ( const node of this.templateElements ) {
|
||||
for ( let i = node.start; i < node.end; i += 1 ) {
|
||||
this.indentExclusions[ node.start + i ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.body.transpile( this.magicString, transforms );
|
||||
}
|
||||
|
||||
Program.prototype = {
|
||||
export ( options = {} ) {
|
||||
return {
|
||||
code: this.magicString.toString(),
|
||||
map: this.magicString.generateMap({
|
||||
file: options.file,
|
||||
source: options.source,
|
||||
includeContent: options.includeContent !== false
|
||||
})
|
||||
};
|
||||
},
|
||||
|
||||
findNearest () {
|
||||
return null;
|
||||
},
|
||||
|
||||
findScope () {
|
||||
return null;
|
||||
}
|
||||
};
|
98
node_modules/buble/src/program/Scope.js
generated
vendored
Normal file
98
node_modules/buble/src/program/Scope.js
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
import extractNames from './extractNames.js';
|
||||
import reserved from '../utils/reserved.js';
|
||||
import CompileError from '../utils/CompileError.js';
|
||||
|
||||
const letConst = /^(?:let|const)$/;
|
||||
|
||||
export default function Scope ( options ) {
|
||||
options = options || {};
|
||||
|
||||
this.parent = options.parent;
|
||||
this.isBlockScope = !!options.block;
|
||||
|
||||
let scope = this;
|
||||
while ( scope.isBlockScope ) scope = scope.parent;
|
||||
this.functionScope = scope;
|
||||
|
||||
this.identifiers = [];
|
||||
this.declarations = Object.create( null );
|
||||
this.references = Object.create( null );
|
||||
this.blockScopedDeclarations = this.isBlockScope ? null : Object.create( null );
|
||||
this.aliases = this.isBlockScope ? null : Object.create( null );
|
||||
}
|
||||
|
||||
Scope.prototype = {
|
||||
addDeclaration ( node, kind ) {
|
||||
for ( const identifier of extractNames( node ) ) {
|
||||
const name = identifier.name;
|
||||
const existingDeclaration = this.declarations[ name ];
|
||||
if ( existingDeclaration && ( letConst.test( kind ) || letConst.test( existingDeclaration.kind ) ) ) {
|
||||
// TODO warn about double var declarations?
|
||||
throw new CompileError( identifier, `${name} is already declared` );
|
||||
}
|
||||
|
||||
const declaration = { name, node: identifier, kind, instances: [] };
|
||||
this.declarations[ name ] = declaration;
|
||||
|
||||
if ( this.isBlockScope ) {
|
||||
if ( !this.functionScope.blockScopedDeclarations[ name ] ) this.functionScope.blockScopedDeclarations[ name ] = [];
|
||||
this.functionScope.blockScopedDeclarations[ name ].push( declaration );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addReference ( identifier ) {
|
||||
if ( this.consolidated ) {
|
||||
this.consolidateReference( identifier );
|
||||
} else {
|
||||
this.identifiers.push( identifier );
|
||||
}
|
||||
},
|
||||
|
||||
consolidate () {
|
||||
for ( let i = 0; i < this.identifiers.length; i += 1 ) { // we might push to the array during consolidation, so don't cache length
|
||||
const identifier = this.identifiers[i];
|
||||
this.consolidateReference( identifier );
|
||||
}
|
||||
|
||||
this.consolidated = true; // TODO understand why this is necessary... seems bad
|
||||
},
|
||||
|
||||
consolidateReference ( identifier ) {
|
||||
const declaration = this.declarations[ identifier.name ];
|
||||
if ( declaration ) {
|
||||
declaration.instances.push( identifier );
|
||||
} else {
|
||||
this.references[ identifier.name ] = true;
|
||||
if ( this.parent ) this.parent.addReference( identifier );
|
||||
}
|
||||
},
|
||||
|
||||
contains ( name ) {
|
||||
return this.declarations[ name ] ||
|
||||
( this.parent ? this.parent.contains( name ) : false );
|
||||
},
|
||||
|
||||
createIdentifier ( base ) {
|
||||
base = base
|
||||
.replace( /\s/g, '' )
|
||||
.replace( /\[([^\]]+)\]/g, '_$1' )
|
||||
.replace( /[^a-zA-Z0-9_$]/g, '_' )
|
||||
.replace( /_{2,}/, '_' );
|
||||
|
||||
let name = base;
|
||||
let counter = 1;
|
||||
|
||||
while ( this.declarations[ name ] || this.references[ name ] || this.aliases[ name ] || name in reserved ) {
|
||||
name = `${base}$${counter++}`;
|
||||
}
|
||||
|
||||
this.aliases[ name ] = true;
|
||||
return name;
|
||||
},
|
||||
|
||||
findDeclaration ( name ) {
|
||||
return this.declarations[ name ] ||
|
||||
( this.parent && this.parent.findDeclaration( name ) );
|
||||
}
|
||||
};
|
31
node_modules/buble/src/program/extractNames.js
generated
vendored
Normal file
31
node_modules/buble/src/program/extractNames.js
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
export default function extractNames ( node ) {
|
||||
const names = [];
|
||||
extractors[ node.type ]( names, node );
|
||||
return names;
|
||||
}
|
||||
|
||||
const extractors = {
|
||||
Identifier ( names, node ) {
|
||||
names.push( node );
|
||||
},
|
||||
|
||||
ObjectPattern ( names, node ) {
|
||||
for ( const prop of node.properties ) {
|
||||
extractors[ prop.value.type ]( names, prop.value );
|
||||
}
|
||||
},
|
||||
|
||||
ArrayPattern ( names, node ) {
|
||||
for ( const element of node.elements ) {
|
||||
if ( element ) extractors[ element.type ]( names, element );
|
||||
}
|
||||
},
|
||||
|
||||
RestElement ( names, node ) {
|
||||
extractors[ node.argument.type ]( names, node.argument );
|
||||
},
|
||||
|
||||
AssignmentPattern ( names, node ) {
|
||||
extractors[ node.left.type ]( names, node.left );
|
||||
}
|
||||
};
|
4
node_modules/buble/src/program/keys.js
generated
vendored
Normal file
4
node_modules/buble/src/program/keys.js
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export default {
|
||||
Program: [ 'body' ],
|
||||
Literal: []
|
||||
};
|
48
node_modules/buble/src/program/types/ArrayExpression.js
generated
vendored
Normal file
48
node_modules/buble/src/program/types/ArrayExpression.js
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import Node from '../Node.js';
|
||||
import spread, { isArguments } from '../../utils/spread.js';
|
||||
|
||||
export default class ArrayExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.spreadRest && this.elements.length ) {
|
||||
const lexicalBoundary = this.findLexicalBoundary();
|
||||
|
||||
let i = this.elements.length;
|
||||
while ( i-- ) {
|
||||
const element = this.elements[i];
|
||||
if ( element && element.type === 'SpreadElement' && isArguments( element.argument ) ) {
|
||||
this.argumentsArrayAlias = lexicalBoundary.getArgumentsArrayAlias();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.spreadRest ) {
|
||||
if ( this.elements.length === 1 ) {
|
||||
const element = this.elements[0];
|
||||
|
||||
if ( element && element.type === 'SpreadElement' ) {
|
||||
// special case – [ ...arguments ]
|
||||
if ( isArguments( element.argument ) ) {
|
||||
code.overwrite( this.start, this.end, `[].concat( ${this.argumentsArrayAlias} )` ); // TODO if this is the only use of argsArray, don't bother concating
|
||||
} else {
|
||||
code.overwrite( this.start, element.argument.start, '[].concat( ' );
|
||||
code.overwrite( element.end, this.end, ' )' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
const hasSpreadElements = spread( code, this.elements, this.start, this.argumentsArrayAlias );
|
||||
|
||||
if ( hasSpreadElements ) {
|
||||
code.overwrite( this.end - 1, this.end, ')' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
30
node_modules/buble/src/program/types/ArrowFunctionExpression.js
generated
vendored
Normal file
30
node_modules/buble/src/program/types/ArrowFunctionExpression.js
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class ArrowFunctionExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
this.body.createScope();
|
||||
super.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.arrow ) {
|
||||
// remove arrow
|
||||
let charIndex = this.body.start;
|
||||
while ( code.original[ charIndex ] !== '=' ) {
|
||||
charIndex -= 1;
|
||||
}
|
||||
code.remove( charIndex, this.body.start );
|
||||
|
||||
// wrap naked parameter
|
||||
if ( this.params.length === 1 && this.start === this.params[0].start ) {
|
||||
code.insertRight( this.params[0].start, '(' );
|
||||
code.insertLeft( this.params[0].end, ')' );
|
||||
}
|
||||
|
||||
// add function
|
||||
code.insertRight( this.start, 'function ' );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
134
node_modules/buble/src/program/types/AssignmentExpression.js
generated
vendored
Normal file
134
node_modules/buble/src/program/types/AssignmentExpression.js
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class AssignmentExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( this.left.type === 'Identifier' ) {
|
||||
const declaration = this.findScope( false ).findDeclaration( this.left.name );
|
||||
if ( declaration && declaration.kind === 'const' ) {
|
||||
throw new CompileError( this.left, `${this.left.name} is read-only` );
|
||||
}
|
||||
|
||||
// special case – https://gitlab.com/Rich-Harris/buble/issues/11
|
||||
const statement = declaration && declaration.node.ancestor( 3 );
|
||||
if ( statement && statement.type === 'ForStatement' && statement.body.contains( this ) ) {
|
||||
statement.reassigned[ this.left.name ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( /Pattern/.test( this.left.type ) ) {
|
||||
throw new CompileError( this.left, 'Destructuring assignments are not currently supported. Coming soon!' );
|
||||
}
|
||||
|
||||
super.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.operator === '**=' && transforms.exponentiation ) {
|
||||
const scope = this.findScope( false );
|
||||
const getAlias = name => {
|
||||
const declaration = scope.findDeclaration( name );
|
||||
return declaration ? declaration.name : name;
|
||||
};
|
||||
|
||||
// first, the easy part – `**=` -> `=`
|
||||
let charIndex = this.left.end;
|
||||
while ( code.original[ charIndex ] !== '*' ) charIndex += 1;
|
||||
code.remove( charIndex, charIndex + 2 );
|
||||
|
||||
// how we do the next part depends on a number of factors – whether
|
||||
// this is a top-level statement, and whether we're updating a
|
||||
// simple or complex reference
|
||||
let base;
|
||||
|
||||
let left = this.left;
|
||||
while ( left.type === 'ParenthesizedExpression' ) left = left.expression;
|
||||
|
||||
if ( left.type === 'Identifier' ) {
|
||||
base = getAlias( left.name );
|
||||
} else if ( left.type === 'MemberExpression' ) {
|
||||
let object;
|
||||
let needsObjectVar = false;
|
||||
let property;
|
||||
let needsPropertyVar = false;
|
||||
|
||||
const statement = this.findNearest( /(?:Statement|Declaration)$/ );
|
||||
const i0 = statement.getIndentation();
|
||||
|
||||
if ( left.property.type === 'Identifier' ) {
|
||||
property = left.computed ? getAlias( left.property.name ) : left.property.name;
|
||||
} else {
|
||||
property = scope.createIdentifier( 'property' );
|
||||
needsPropertyVar = true;
|
||||
}
|
||||
|
||||
if ( left.object.type === 'Identifier' ) {
|
||||
object = getAlias( left.object.name );
|
||||
} else {
|
||||
object = scope.createIdentifier( 'object' );
|
||||
needsObjectVar = true;
|
||||
}
|
||||
|
||||
if ( left.start === statement.start ) {
|
||||
if ( needsObjectVar && needsPropertyVar ) {
|
||||
code.insertRight( statement.start, `var ${object} = ` );
|
||||
code.overwrite( left.object.end, left.property.start, `;\n${i0}var ${property} = ` );
|
||||
code.overwrite( left.property.end, left.end, `;\n${i0}${object}[${property}]` );
|
||||
}
|
||||
|
||||
else if ( needsObjectVar ) {
|
||||
code.insertRight( statement.start, `var ${object} = ` );
|
||||
code.insertLeft( left.object.end, `;\n${i0}` );
|
||||
code.insertLeft( left.object.end, object );
|
||||
}
|
||||
|
||||
else if ( needsPropertyVar ) {
|
||||
code.insertRight( left.property.start, `var ${property} = ` );
|
||||
code.insertLeft( left.property.end, `;\n${i0}` );
|
||||
code.move( left.property.start, left.property.end, this.start );
|
||||
|
||||
code.insertLeft( left.object.end, `[${property}]` );
|
||||
code.remove( left.object.end, left.property.start );
|
||||
code.remove( left.property.end, left.end );
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
let declarators = [];
|
||||
if ( needsObjectVar ) declarators.push( object );
|
||||
if ( needsPropertyVar ) declarators.push( property );
|
||||
code.insertRight( statement.start, `var ${declarators.join( ', ' )};\n${i0}` );
|
||||
|
||||
if ( needsObjectVar && needsPropertyVar ) {
|
||||
code.insertRight( left.start, `( ${object} = ` );
|
||||
code.overwrite( left.object.end, left.property.start, `, ${property} = ` );
|
||||
code.overwrite( left.property.end, left.end, `, ${object}[${property}]` );
|
||||
}
|
||||
|
||||
else if ( needsObjectVar ) {
|
||||
code.insertRight( left.start, `( ${object} = ` );
|
||||
code.insertLeft( left.object.end, `, ${object}` );
|
||||
}
|
||||
|
||||
else if ( needsPropertyVar ) {
|
||||
code.insertRight( left.property.start, `( ${property} = ` );
|
||||
code.insertLeft( left.property.end, `, ` );
|
||||
code.move( left.property.start, left.property.end, left.start );
|
||||
|
||||
code.overwrite( left.object.end, left.property.start, `[${property}]` );
|
||||
code.remove( left.property.end, left.end );
|
||||
}
|
||||
|
||||
code.insertLeft( this.end, ` )` );
|
||||
}
|
||||
|
||||
base = object + ( left.computed || needsPropertyVar ? `[${property}]` : `.${property}` );
|
||||
}
|
||||
|
||||
code.insertRight( this.right.start, `Math.pow( ${base}, ` );
|
||||
code.insertLeft( this.right.end, ` )` );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
12
node_modules/buble/src/program/types/BinaryExpression.js
generated
vendored
Normal file
12
node_modules/buble/src/program/types/BinaryExpression.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class BinaryExpression extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.operator === '**' && transforms.exponentiation ) {
|
||||
code.insertRight( this.start, `Math.pow( ` );
|
||||
code.overwrite( this.left.end, this.right.start, `, ` );
|
||||
code.insertLeft( this.end, ` )` );
|
||||
}
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
21
node_modules/buble/src/program/types/BreakStatement.js
generated
vendored
Normal file
21
node_modules/buble/src/program/types/BreakStatement.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class BreakStatement extends Node {
|
||||
initialise ( transforms ) {
|
||||
const loop = this.findNearest( /(?:For(?:In)?|While)Statement/ );
|
||||
const switchCase = this.findNearest( 'SwitchCase' );
|
||||
|
||||
if ( loop && ( !switchCase || loop.depth > switchCase.depth ) ) {
|
||||
loop.canBreak = true;
|
||||
this.loop = loop;
|
||||
}
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.loop && this.loop.shouldRewriteAsFunction ) {
|
||||
if ( this.label ) throw new CompileError( this, 'Labels are not currently supported in a loop with locally-scoped variables' );
|
||||
code.overwrite( this.start, this.start + 5, `return 'break'` );
|
||||
}
|
||||
}
|
||||
}
|
86
node_modules/buble/src/program/types/CallExpression.js
generated
vendored
Normal file
86
node_modules/buble/src/program/types/CallExpression.js
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
import Node from '../Node.js';
|
||||
import spread, { isArguments } from '../../utils/spread.js';
|
||||
|
||||
export default class CallExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.spreadRest && this.arguments.length > 1 ) {
|
||||
const lexicalBoundary = this.findLexicalBoundary();
|
||||
|
||||
let i = this.arguments.length;
|
||||
while ( i-- ) {
|
||||
const arg = this.arguments[i];
|
||||
if ( arg.type === 'SpreadElement' && isArguments( arg.argument ) ) {
|
||||
this.argumentsArrayAlias = lexicalBoundary.getArgumentsArrayAlias();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.spreadRest && this.arguments.length ) {
|
||||
let hasSpreadElements = false;
|
||||
let context;
|
||||
|
||||
const firstArgument = this.arguments[0];
|
||||
|
||||
if ( this.arguments.length === 1 ) {
|
||||
if ( firstArgument.type === 'SpreadElement' ) {
|
||||
code.remove( firstArgument.start, firstArgument.argument.start );
|
||||
hasSpreadElements = true;
|
||||
}
|
||||
} else {
|
||||
hasSpreadElements = spread( code, this.arguments, firstArgument.start, this.argumentsArrayAlias );
|
||||
}
|
||||
|
||||
if ( hasSpreadElements ) {
|
||||
if ( this.callee.type === 'MemberExpression' ) {
|
||||
if ( this.callee.object.type === 'Identifier' ) {
|
||||
context = this.callee.object.name;
|
||||
} else {
|
||||
const statement = this.callee.object;
|
||||
const i0 = statement.getIndentation();
|
||||
context = this.findScope( true ).createIdentifier( 'ref' );
|
||||
code.insertRight( statement.start, `var ${context} = ` );
|
||||
code.insertLeft( statement.end, `;\n${i0}${context}` );
|
||||
}
|
||||
} else {
|
||||
context = 'void 0';
|
||||
}
|
||||
|
||||
code.insertLeft( this.callee.end, '.apply' );
|
||||
|
||||
// we need to handle `super()` different, because `SuperClass.call.apply`
|
||||
// isn't very helpful
|
||||
const isSuper = this.callee.type === 'Super';
|
||||
|
||||
if ( isSuper ) {
|
||||
this.callee.noCall = true; // bit hacky...
|
||||
|
||||
if ( this.arguments.length > 1 ) {
|
||||
if ( firstArgument.type !== 'SpreadElement' ) {
|
||||
code.insertRight( firstArgument.start, `[ ` );
|
||||
}
|
||||
|
||||
code.insertLeft( this.arguments[ this.arguments.length - 1 ].end, ' )' );
|
||||
}
|
||||
}
|
||||
|
||||
else if ( this.arguments.length === 1 ) {
|
||||
code.insertRight( firstArgument.start, `${context}, ` );
|
||||
} else {
|
||||
if ( firstArgument.type === 'SpreadElement' ) {
|
||||
code.insertRight( firstArgument.start, `${context}, ` );
|
||||
} else {
|
||||
code.insertRight( firstArgument.start, `${context}, [ ` );
|
||||
}
|
||||
|
||||
code.insertLeft( this.arguments[ this.arguments.length - 1 ].end, ' )' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
164
node_modules/buble/src/program/types/ClassBody.js
generated
vendored
Normal file
164
node_modules/buble/src/program/types/ClassBody.js
generated
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
import Node from '../Node.js';
|
||||
import { findIndex } from '../../utils/array.js';
|
||||
import reserved from '../../utils/reserved.js';
|
||||
|
||||
// TODO this code is pretty wild, tidy it up
|
||||
export default class ClassBody extends Node {
|
||||
transpile ( code, transforms, inFunctionExpression, superName ) {
|
||||
if ( transforms.classes ) {
|
||||
const name = this.parent.name;
|
||||
|
||||
const indentStr = code.getIndentString();
|
||||
const i0 = this.getIndentation() + ( inFunctionExpression ? indentStr : '' );
|
||||
const i1 = i0 + indentStr;
|
||||
|
||||
const constructorIndex = findIndex( this.body, node => node.kind === 'constructor' );
|
||||
const constructor = this.body[ constructorIndex ];
|
||||
|
||||
let introBlock = '';
|
||||
let outroBlock = '';
|
||||
|
||||
if ( this.body.length ) {
|
||||
code.remove( this.start, this.body[0].start );
|
||||
code.remove( this.body[ this.body.length - 1 ].end, this.end );
|
||||
} else {
|
||||
code.remove( this.start, this.end );
|
||||
}
|
||||
|
||||
if ( constructor ) {
|
||||
constructor.value.body.isConstructorBody = true;
|
||||
|
||||
const previousMethod = this.body[ constructorIndex - 1 ];
|
||||
const nextMethod = this.body[ constructorIndex + 1 ];
|
||||
|
||||
// ensure constructor is first
|
||||
if ( constructorIndex > 0 ) {
|
||||
code.remove( previousMethod.end, constructor.start );
|
||||
code.move( constructor.start, nextMethod ? nextMethod.start : this.end - 1, this.body[0].start );
|
||||
}
|
||||
|
||||
if ( !inFunctionExpression ) code.insertLeft( constructor.end, ';' );
|
||||
}
|
||||
|
||||
if ( this.parent.superClass ) {
|
||||
let inheritanceBlock = `if ( ${superName} ) ${name}.__proto__ = ${superName};\n${i0}${name}.prototype = Object.create( ${superName} && ${superName}.prototype );\n${i0}${name}.prototype.constructor = ${name};`;
|
||||
|
||||
if ( constructor ) {
|
||||
introBlock += `\n\n${i0}` + inheritanceBlock;
|
||||
} else {
|
||||
const fn = `function ${name} () {` + ( superName ?
|
||||
`\n${i1}${superName}.apply(this, arguments);\n${i0}}` :
|
||||
`}` ) + ( inFunctionExpression ? '' : ';' ) + ( this.body.length ? `\n\n${i0}` : '' );
|
||||
|
||||
inheritanceBlock = fn + inheritanceBlock;
|
||||
introBlock += inheritanceBlock + `\n\n${i0}`;
|
||||
}
|
||||
} else if ( !constructor ) {
|
||||
let fn = `function ${name} () {}`;
|
||||
if ( this.parent.type === 'ClassDeclaration' ) fn += ';';
|
||||
if ( this.body.length ) fn += `\n\n${i0}`;
|
||||
|
||||
introBlock += fn;
|
||||
}
|
||||
|
||||
const scope = this.findScope( false );
|
||||
|
||||
let prototypeGettersAndSetters = [];
|
||||
let staticGettersAndSetters = [];
|
||||
let prototypeAccessors;
|
||||
let staticAccessors;
|
||||
|
||||
this.body.forEach( ( method, i ) => {
|
||||
if ( method.kind === 'constructor' ) {
|
||||
code.overwrite( method.key.start, method.key.end, `function ${name}` );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( method.static ) code.remove( method.start, method.start + 7 );
|
||||
|
||||
const isAccessor = method.kind !== 'method';
|
||||
let lhs;
|
||||
|
||||
let methodName = method.key.name;
|
||||
if ( scope.contains( methodName ) || reserved[ methodName ] ) methodName = scope.createIdentifier( methodName );
|
||||
|
||||
if ( isAccessor ) {
|
||||
if ( method.computed ) {
|
||||
throw new Error( 'Computed accessor properties are not currently supported' );
|
||||
}
|
||||
|
||||
code.remove( method.start, method.key.start );
|
||||
|
||||
if ( method.static ) {
|
||||
if ( !~staticGettersAndSetters.indexOf( method.key.name ) ) staticGettersAndSetters.push( method.key.name );
|
||||
if ( !staticAccessors ) staticAccessors = scope.createIdentifier( 'staticAccessors' );
|
||||
|
||||
lhs = `${staticAccessors}`;
|
||||
} else {
|
||||
if ( !~prototypeGettersAndSetters.indexOf( method.key.name ) ) prototypeGettersAndSetters.push( method.key.name );
|
||||
if ( !prototypeAccessors ) prototypeAccessors = scope.createIdentifier( 'prototypeAccessors' );
|
||||
|
||||
lhs = `${prototypeAccessors}`;
|
||||
}
|
||||
} else {
|
||||
lhs = method.static ?
|
||||
`${name}` :
|
||||
`${name}.prototype`;
|
||||
}
|
||||
|
||||
if ( !method.computed ) lhs += '.';
|
||||
|
||||
const insertNewlines = ( constructorIndex > 0 && i === constructorIndex + 1 ) ||
|
||||
( i === 0 && constructorIndex === this.body.length - 1 );
|
||||
|
||||
if ( insertNewlines ) lhs = `\n\n${i0}${lhs}`;
|
||||
|
||||
let c = method.key.end;
|
||||
if ( method.computed ) {
|
||||
while ( code.original[c] !== ']' ) c += 1;
|
||||
c += 1;
|
||||
}
|
||||
|
||||
code.insertRight( method.start, lhs );
|
||||
|
||||
const rhs = ( isAccessor ? `.${method.kind}` : '' ) + ` = function` + ( method.value.generator ? '* ' : ' ' ) + ( method.computed || isAccessor ? '' : `${methodName} ` );
|
||||
code.remove( c, method.value.start );
|
||||
code.insertRight( method.value.start, rhs );
|
||||
code.insertLeft( method.end, ';' );
|
||||
|
||||
if ( method.value.generator ) code.remove( method.start, method.key.start );
|
||||
});
|
||||
|
||||
if ( prototypeGettersAndSetters.length || staticGettersAndSetters.length ) {
|
||||
let intro = [];
|
||||
let outro = [];
|
||||
|
||||
if ( prototypeGettersAndSetters.length ) {
|
||||
intro.push( `var ${prototypeAccessors} = { ${prototypeGettersAndSetters.map( name => `${name}: {}` ).join( ',' )} };` );
|
||||
outro.push( `Object.defineProperties( ${name}.prototype, ${prototypeAccessors} );` );
|
||||
}
|
||||
|
||||
if ( staticGettersAndSetters.length ) {
|
||||
intro.push( `var ${staticAccessors} = { ${staticGettersAndSetters.map( name => `${name}: {}` ).join( ',' )} };` );
|
||||
outro.push( `Object.defineProperties( ${name}, ${staticAccessors} );` );
|
||||
}
|
||||
|
||||
if ( constructor ) introBlock += `\n\n${i0}`;
|
||||
introBlock += intro.join( `\n${i0}` );
|
||||
if ( !constructor ) introBlock += `\n\n${i0}`;
|
||||
|
||||
outroBlock += `\n\n${i0}` + outro.join( `\n${i0}` );
|
||||
}
|
||||
|
||||
if ( constructor ) {
|
||||
code.insertLeft( constructor.end, introBlock );
|
||||
} else {
|
||||
code.insertRight( this.start, introBlock );
|
||||
}
|
||||
|
||||
code.insertLeft( this.end, outroBlock );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
62
node_modules/buble/src/program/types/ClassDeclaration.js
generated
vendored
Normal file
62
node_modules/buble/src/program/types/ClassDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
import Node from '../Node.js';
|
||||
import deindent from '../../utils/deindent.js';
|
||||
|
||||
export default class ClassDeclaration extends Node {
|
||||
initialise ( transforms ) {
|
||||
this.name = this.id.name;
|
||||
this.findScope( true ).addDeclaration( this.id, 'class' );
|
||||
|
||||
super.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.classes ) {
|
||||
if ( !this.superClass ) deindent( this.body, code );
|
||||
|
||||
const superName = this.superClass && ( this.superClass.name || 'superclass' );
|
||||
|
||||
const i0 = this.getIndentation();
|
||||
const i1 = i0 + code.getIndentString();
|
||||
|
||||
// if this is an export default statement, we have to move the export to
|
||||
// after the declaration, because `export default var Foo = ...` is illegal
|
||||
const syntheticDefaultExport = this.parent.type === 'ExportDefaultDeclaration' ?
|
||||
`\n\n${i0}export default ${this.id.name};` :
|
||||
'';
|
||||
|
||||
if ( syntheticDefaultExport ) code.remove( this.parent.start, this.start );
|
||||
|
||||
code.overwrite( this.start, this.id.start, 'var ' );
|
||||
|
||||
if ( this.superClass ) {
|
||||
if ( this.superClass.end === this.body.start ) {
|
||||
code.remove( this.id.end, this.superClass.start );
|
||||
code.insertLeft( this.id.end, ` = (function (${superName}) {\n${i1}` );
|
||||
} else {
|
||||
code.overwrite( this.id.end, this.superClass.start, ' = ' );
|
||||
code.overwrite( this.superClass.end, this.body.start, `(function (${superName}) {\n${i1}` );
|
||||
}
|
||||
} else {
|
||||
if ( this.id.end === this.body.start ) {
|
||||
code.insertLeft( this.id.end, ' = ' );
|
||||
} else {
|
||||
code.overwrite( this.id.end, this.body.start, ' = ' );
|
||||
}
|
||||
}
|
||||
|
||||
this.body.transpile( code, transforms, !!this.superClass, superName );
|
||||
|
||||
if ( this.superClass ) {
|
||||
code.insertLeft( this.end, `\n\n${i1}return ${this.name};\n${i0}}(` );
|
||||
code.move( this.superClass.start, this.superClass.end, this.end );
|
||||
code.insertRight( this.end, `));${syntheticDefaultExport}` );
|
||||
} else if ( syntheticDefaultExport ) {
|
||||
code.insertRight( this.end, syntheticDefaultExport );
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
this.body.transpile( code, transforms, false, null );
|
||||
}
|
||||
}
|
||||
}
|
45
node_modules/buble/src/program/types/ClassExpression.js
generated
vendored
Normal file
45
node_modules/buble/src/program/types/ClassExpression.js
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class ClassExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
this.name = this.id ? this.id.name :
|
||||
this.parent.type === 'VariableDeclarator' ? this.parent.id.name :
|
||||
this.parent.type === 'AssignmentExpression' ? this.parent.left.name :
|
||||
this.findScope( true ).createIdentifier( 'anonymous' );
|
||||
|
||||
super.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.classes ) {
|
||||
const superName = this.superClass && ( this.superClass.name || 'superclass' );
|
||||
|
||||
const i0 = this.getIndentation();
|
||||
const i1 = i0 + code.getIndentString();
|
||||
|
||||
if ( this.superClass ) {
|
||||
code.remove( this.start, this.superClass.start );
|
||||
code.remove( this.superClass.end, this.body.start );
|
||||
code.insertLeft( this.start, `(function (${superName}) {\n${i1}` );
|
||||
} else {
|
||||
code.overwrite( this.start, this.body.start, `(function () {\n${i1}` );
|
||||
}
|
||||
|
||||
this.body.transpile( code, transforms, true, superName );
|
||||
|
||||
const outro = `\n\n${i1}return ${this.name};\n${i0}}(`;
|
||||
|
||||
if ( this.superClass ) {
|
||||
code.insertLeft( this.end, outro );
|
||||
code.move( this.superClass.start, this.superClass.end, this.end );
|
||||
code.insertRight( this.end, '))' );
|
||||
} else {
|
||||
code.insertLeft( this.end, `\n\n${i1}return ${this.name};\n${i0}}())` );
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
this.body.transpile( code, transforms, false );
|
||||
}
|
||||
}
|
||||
}
|
12
node_modules/buble/src/program/types/ContinueStatement.js
generated
vendored
Normal file
12
node_modules/buble/src/program/types/ContinueStatement.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class ContinueStatement extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
const loop = this.findNearest( /(?:For(?:In|Of)?|While)Statement/ );
|
||||
if ( loop.shouldRewriteAsFunction ) {
|
||||
if ( this.label ) throw new CompileError( this, 'Labels are not currently supported in a loop with locally-scoped variables' );
|
||||
code.overwrite( this.start, this.start + 8, 'return' );
|
||||
}
|
||||
}
|
||||
}
|
9
node_modules/buble/src/program/types/ExportDefaultDeclaration.js
generated
vendored
Normal file
9
node_modules/buble/src/program/types/ExportDefaultDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
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 );
|
||||
}
|
||||
}
|
9
node_modules/buble/src/program/types/ExportNamedDeclaration.js
generated
vendored
Normal file
9
node_modules/buble/src/program/types/ExportNamedDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class ExportNamedDeclaration extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.moduleExport ) throw new CompileError( this, 'export is not supported' );
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
22
node_modules/buble/src/program/types/ForInStatement.js
generated
vendored
Normal file
22
node_modules/buble/src/program/types/ForInStatement.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import LoopStatement from './shared/LoopStatement.js';
|
||||
import extractNames from '../extractNames.js';
|
||||
|
||||
export default class ForInStatement extends LoopStatement {
|
||||
findScope ( functionScope ) {
|
||||
return functionScope || !this.createdScope ? this.parent.findScope( functionScope ) : this.body.scope;
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.shouldRewriteAsFunction ) {
|
||||
// which variables are declared in the init statement?
|
||||
const names = this.left.type === 'VariableDeclaration' ?
|
||||
[].concat.apply( [], this.left.declarations.map( declarator => extractNames( declarator.id ) ) ) :
|
||||
[];
|
||||
|
||||
this.args = names.map( name => name in this.aliases ? this.aliases[ name ].outer : name );
|
||||
this.params = names.map( name => name in this.aliases ? this.aliases[ name ].inner : name );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
52
node_modules/buble/src/program/types/ForOfStatement.js
generated
vendored
Normal file
52
node_modules/buble/src/program/types/ForOfStatement.js
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
import LoopStatement from './shared/LoopStatement.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class ForOfStatement extends LoopStatement {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.forOf && !transforms.dangerousForOf ) throw new CompileError( this, 'for...of statements are not supported. Use `transforms: { forOf: false }` to skip transformation and disable this error, or `transforms: { dangerousForOf: true }` if you know what you\'re doing' );
|
||||
super.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( !transforms.dangerousForOf ) {
|
||||
super.transpile( code, transforms );
|
||||
return;
|
||||
}
|
||||
|
||||
// edge case (#80)
|
||||
if ( !this.body.body[0] ) {
|
||||
if ( this.left.type === 'VariableDeclaration' && this.left.kind === 'var' ) {
|
||||
code.remove( this.start, this.left.start );
|
||||
code.insertLeft( this.left.end, ';' );
|
||||
code.remove( this.left.end, this.end );
|
||||
} else {
|
||||
code.remove( this.start, this.end );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const scope = this.findScope( true );
|
||||
const i0 = this.getIndentation();
|
||||
const i1 = i0 + code.getIndentString();
|
||||
|
||||
const key = scope.createIdentifier( 'i' );
|
||||
const list = scope.createIdentifier( 'list' );
|
||||
|
||||
if ( this.body.synthetic ) {
|
||||
code.insertRight( this.left.start, `{\n${i1}` );
|
||||
code.insertLeft( this.body.body[0].end, `\n${i0}}` );
|
||||
}
|
||||
|
||||
const bodyStart = this.body.body[0].start;
|
||||
|
||||
code.remove( this.left.end, this.right.start );
|
||||
code.move( this.left.start, this.left.end, bodyStart );
|
||||
code.insertLeft( this.left.end, ` = ${list}[${key}];\n\n${i1}` );
|
||||
|
||||
code.insertRight( this.right.start, `var ${key} = 0, ${list} = ` );
|
||||
code.insertLeft( this.right.end, `; ${key} < ${list}.length; ${key} += 1` );
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
38
node_modules/buble/src/program/types/ForStatement.js
generated
vendored
Normal file
38
node_modules/buble/src/program/types/ForStatement.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
import LoopStatement from './shared/LoopStatement.js';
|
||||
import extractNames from '../extractNames.js';
|
||||
|
||||
export default class ForStatement extends LoopStatement {
|
||||
findScope ( functionScope ) {
|
||||
return functionScope || !this.createdScope ? this.parent.findScope( functionScope ) : this.body.scope;
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
const i1 = this.getIndentation() + code.getIndentString();
|
||||
|
||||
if ( this.shouldRewriteAsFunction ) {
|
||||
// which variables are declared in the init statement?
|
||||
const names = this.init.type === 'VariableDeclaration' ?
|
||||
[].concat.apply( [], this.init.declarations.map( declarator => extractNames( declarator.id ) ) ) :
|
||||
[];
|
||||
|
||||
const aliases = this.aliases;
|
||||
|
||||
this.args = names.map( name => name in this.aliases ? this.aliases[ name ].outer : name );
|
||||
this.params = names.map( name => name in this.aliases ? this.aliases[ name ].inner : name );
|
||||
|
||||
const updates = Object.keys( this.reassigned )
|
||||
.map( name => `${aliases[ name ].outer} = ${aliases[ name ].inner};` );
|
||||
|
||||
if ( updates.length ) {
|
||||
if ( this.body.synthetic ) {
|
||||
code.insertLeft( this.body.body[0].end, `; ${updates.join(` `)}` );
|
||||
} else {
|
||||
const lastStatement = this.body.body[ this.body.body.length - 1 ];
|
||||
code.insertLeft( lastStatement.end, `\n\n${i1}${updates.join(`\n${i1}`)}` );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
15
node_modules/buble/src/program/types/FunctionDeclaration.js
generated
vendored
Normal file
15
node_modules/buble/src/program/types/FunctionDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class FunctionDeclaration extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( this.generator && transforms.generator ) {
|
||||
throw new CompileError( this, 'Generators are not supported' );
|
||||
}
|
||||
|
||||
this.body.createScope();
|
||||
|
||||
this.findScope( true ).addDeclaration( this.id, 'function' );
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
19
node_modules/buble/src/program/types/FunctionExpression.js
generated
vendored
Normal file
19
node_modules/buble/src/program/types/FunctionExpression.js
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class FunctionExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( this.generator && transforms.generator ) {
|
||||
throw new CompileError( this, 'Generators are not supported' );
|
||||
}
|
||||
|
||||
this.body.createScope();
|
||||
|
||||
if ( this.id ) {
|
||||
// function expression IDs belong to the child scope...
|
||||
this.body.scope.addDeclaration( this.id, 'function' );
|
||||
}
|
||||
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
42
node_modules/buble/src/program/types/Identifier.js
generated
vendored
Normal file
42
node_modules/buble/src/program/types/Identifier.js
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
import Node from '../Node.js';
|
||||
import isReference from '../../utils/isReference.js';
|
||||
|
||||
export default class Identifier extends Node {
|
||||
findScope ( functionScope ) {
|
||||
if ( this.parent.params && ~this.parent.params.indexOf( this ) ) {
|
||||
return this.parent.body.scope;
|
||||
}
|
||||
|
||||
if ( this.parent.type === 'FunctionExpression' && this === this.parent.id ) {
|
||||
return this.parent.body.scope;
|
||||
}
|
||||
|
||||
return this.parent.findScope( functionScope );
|
||||
}
|
||||
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.arrow && isReference( this, this.parent ) ) {
|
||||
if ( this.name === 'arguments' && !this.findScope( false ).contains( this.name ) ) {
|
||||
const lexicalBoundary = this.findLexicalBoundary();
|
||||
const arrowFunction = this.findNearest( 'ArrowFunctionExpression' );
|
||||
const loop = this.findNearest( /(?:For(?:In|Of)?|While)Statement/ );
|
||||
|
||||
if ( arrowFunction && arrowFunction.depth > lexicalBoundary.depth ) {
|
||||
this.alias = lexicalBoundary.getArgumentsAlias();
|
||||
}
|
||||
|
||||
if ( loop && loop.body.contains( this ) && loop.depth > lexicalBoundary.depth ) {
|
||||
this.alias = lexicalBoundary.getArgumentsAlias();
|
||||
}
|
||||
}
|
||||
|
||||
this.findScope( false ).addReference( this );
|
||||
}
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.alias ) {
|
||||
code.overwrite( this.start, this.end, this.alias, true );
|
||||
}
|
||||
}
|
||||
}
|
9
node_modules/buble/src/program/types/ImportDeclaration.js
generated
vendored
Normal file
9
node_modules/buble/src/program/types/ImportDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class ImportDeclaration extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.moduleImport ) throw new CompileError( this, 'import is not supported' );
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
8
node_modules/buble/src/program/types/ImportDefaultSpecifier.js
generated
vendored
Normal file
8
node_modules/buble/src/program/types/ImportDefaultSpecifier.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class ImportDefaultSpecifier extends Node {
|
||||
initialise ( transforms ) {
|
||||
this.findScope( true ).addDeclaration( this.local, 'import' );
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
8
node_modules/buble/src/program/types/ImportSpecifier.js
generated
vendored
Normal file
8
node_modules/buble/src/program/types/ImportSpecifier.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class ImportSpecifier extends Node {
|
||||
initialise ( transforms ) {
|
||||
this.findScope( true ).addDeclaration( this.local, 'import' );
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
20
node_modules/buble/src/program/types/JSXAttribute.js
generated
vendored
Normal file
20
node_modules/buble/src/program/types/JSXAttribute.js
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
const IS_DATA_ATTRIBUTE = /-/;
|
||||
|
||||
export default class JSXAttribute extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.value ) {
|
||||
code.overwrite( this.name.end, this.value.start, ': ' );
|
||||
} else {
|
||||
// tag without value
|
||||
code.overwrite( this.name.start, this.name.end, `${this.name.name}: true`)
|
||||
}
|
||||
|
||||
if ( IS_DATA_ATTRIBUTE.test( this.name.name ) ) {
|
||||
code.overwrite( this.name.start, this.name.end, `'${this.name.name}'` );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
22
node_modules/buble/src/program/types/JSXClosingElement.js
generated
vendored
Normal file
22
node_modules/buble/src/program/types/JSXClosingElement.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
function containsNewLine ( node ) {
|
||||
return node.type === 'Literal' && !/\S/.test( node.value ) && /\n/.test( node.value );
|
||||
}
|
||||
|
||||
export default class JSXClosingElement extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
let spaceBeforeParen = true;
|
||||
|
||||
const lastChild = this.parent.children[ this.parent.children.length - 1 ];
|
||||
|
||||
// omit space before closing paren if
|
||||
// a) this is on a separate line, or
|
||||
// b) there are no children but there are attributes
|
||||
if ( ( lastChild && containsNewLine( lastChild ) ) || ( this.parent.openingElement.attributes.length ) ) {
|
||||
spaceBeforeParen = false;
|
||||
}
|
||||
|
||||
code.overwrite( this.start, this.end, spaceBeforeParen ? ' )' : ')' );
|
||||
}
|
||||
}
|
46
node_modules/buble/src/program/types/JSXElement.js
generated
vendored
Normal file
46
node_modules/buble/src/program/types/JSXElement.js
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
function normalise ( str, removeTrailingWhitespace ) {
|
||||
if ( removeTrailingWhitespace && /\n/.test( str ) ) {
|
||||
str = str.replace( /\s+$/, '' );
|
||||
}
|
||||
|
||||
str = str
|
||||
.replace( /^\n\r?\s+/, '' ) // remove leading newline + space
|
||||
.replace( /\s*\n\r?\s*/gm, ' ' ); // replace newlines with spaces
|
||||
|
||||
// TODO prefer single quotes?
|
||||
return JSON.stringify( str );
|
||||
}
|
||||
|
||||
export default class JSXElement extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
super.transpile( code, transforms );
|
||||
|
||||
const children = this.children.filter( child => {
|
||||
if ( child.type !== 'Literal' ) return true;
|
||||
|
||||
// remove whitespace-only literals, unless on a single line
|
||||
return /\S/.test( child.value ) || !/\n/.test( child.value );
|
||||
});
|
||||
|
||||
if ( children.length ) {
|
||||
let c = this.openingElement.end;
|
||||
|
||||
let i;
|
||||
for ( i = 0; i < children.length; i += 1 ) {
|
||||
const child = children[i];
|
||||
|
||||
const tail = code.original[ c ] === '\n' && child.type !== 'Literal' ? '' : ' ';
|
||||
code.insertLeft( c, `,${tail}` );
|
||||
|
||||
if ( child.type === 'Literal' ) {
|
||||
const str = normalise( child.value, i === children.length - 1 );
|
||||
code.overwrite( child.start, child.end, str );
|
||||
}
|
||||
|
||||
c = child.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
node_modules/buble/src/program/types/JSXExpressionContainer.js
generated
vendored
Normal file
10
node_modules/buble/src/program/types/JSXExpressionContainer.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class JSXExpressionContainer extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
code.remove( this.start, this.expression.start );
|
||||
code.remove( this.expression.end, this.end );
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
81
node_modules/buble/src/program/types/JSXOpeningElement.js
generated
vendored
Normal file
81
node_modules/buble/src/program/types/JSXOpeningElement.js
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class JSXOpeningElement extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
code.overwrite( this.start, this.name.start, `${this.program.jsx}( ` );
|
||||
|
||||
const html = this.name.type === 'JSXIdentifier' && this.name.name[0] === this.name.name[0].toLowerCase();
|
||||
if ( html ) code.insertRight( this.name.start, `'` );
|
||||
|
||||
const len = this.attributes.length;
|
||||
let c = this.name.end;
|
||||
|
||||
if ( len ) {
|
||||
let i;
|
||||
|
||||
let hasSpread = false;
|
||||
for ( i = 0; i < len; i += 1 ) {
|
||||
if ( this.attributes[i].type === 'JSXSpreadAttribute' ) {
|
||||
hasSpread = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c = this.attributes[0].end;
|
||||
|
||||
for ( i = 0; i < len; i += 1 ) {
|
||||
const attr = this.attributes[i];
|
||||
|
||||
if ( i > 0 ) {
|
||||
code.overwrite( c, attr.start, ', ' );
|
||||
}
|
||||
|
||||
if ( hasSpread && attr.type !== 'JSXSpreadAttribute' ) {
|
||||
const lastAttr = this.attributes[ i - 1 ];
|
||||
const nextAttr = this.attributes[ i + 1 ];
|
||||
|
||||
if ( !lastAttr || lastAttr.type === 'JSXSpreadAttribute' ) {
|
||||
code.insertRight( attr.start, '{ ' );
|
||||
}
|
||||
|
||||
if ( !nextAttr || nextAttr.type === 'JSXSpreadAttribute' ) {
|
||||
code.insertLeft( attr.end, ' }' );
|
||||
}
|
||||
}
|
||||
|
||||
c = attr.end;
|
||||
}
|
||||
|
||||
let after;
|
||||
let before;
|
||||
if ( hasSpread ) {
|
||||
if ( len === 1 ) {
|
||||
before = html ? `',` : ',';
|
||||
} else {
|
||||
before = html ? `', ${this.program.objectAssign}({},` : `, ${this.program.objectAssign}({},`;
|
||||
after = ')';
|
||||
}
|
||||
} else {
|
||||
before = html ? `', {` : ', {';
|
||||
after = ' }';
|
||||
}
|
||||
|
||||
code.insertRight( this.name.end, before );
|
||||
|
||||
if ( after ) {
|
||||
code.insertLeft( this.attributes[ len - 1 ].end, after );
|
||||
}
|
||||
} else {
|
||||
code.insertLeft( this.name.end, html ? `', null` : `, null` );
|
||||
c = this.name.end;
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
|
||||
if ( this.selfClosing ) {
|
||||
code.overwrite( c, this.end, this.attributes.length ? `)` : ` )` );
|
||||
} else {
|
||||
code.remove( c, this.end );
|
||||
}
|
||||
}
|
||||
}
|
10
node_modules/buble/src/program/types/JSXSpreadAttribute.js
generated
vendored
Normal file
10
node_modules/buble/src/program/types/JSXSpreadAttribute.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class JSXSpreadAttribute extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
code.remove( this.start, this.argument.start );
|
||||
code.remove( this.argument.end, this.end );
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
23
node_modules/buble/src/program/types/Literal.js
generated
vendored
Normal file
23
node_modules/buble/src/program/types/Literal.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
import rewritePattern from 'regexpu-core';
|
||||
|
||||
export default class Literal extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.numericLiteral ) {
|
||||
const leading = this.raw.slice( 0, 2 );
|
||||
if ( leading === '0b' || leading === '0o' ) {
|
||||
code.overwrite( this.start, this.end, String( this.value ), true );
|
||||
}
|
||||
}
|
||||
|
||||
if ( this.regex ) {
|
||||
const { pattern, flags } = this.regex;
|
||||
|
||||
if ( transforms.stickyRegExp && /y/.test( flags ) ) throw new CompileError( this, 'Regular expression sticky flag is not supported' );
|
||||
if ( transforms.unicodeRegExp && /u/.test( flags ) ) {
|
||||
code.overwrite( this.start, this.end, `/${rewritePattern( pattern, flags )}/${flags.replace( 'u', '' )}` );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
node_modules/buble/src/program/types/MemberExpression.js
generated
vendored
Normal file
13
node_modules/buble/src/program/types/MemberExpression.js
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
import Node from '../Node.js';
|
||||
import reserved from '../../utils/reserved.js';
|
||||
|
||||
export default class MemberExpression extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.reservedProperties && reserved[ this.property.name ] ) {
|
||||
code.overwrite( this.object.end, this.property.start, `['` );
|
||||
code.insertLeft( this.property.end, `']` );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
121
node_modules/buble/src/program/types/ObjectExpression.js
generated
vendored
Normal file
121
node_modules/buble/src/program/types/ObjectExpression.js
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
import Node from '../Node.js';
|
||||
import deindent from '../../utils/deindent.js';
|
||||
|
||||
export default class ObjectExpression extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
super.transpile( code, transforms );
|
||||
|
||||
let spreadPropertyCount = 0;
|
||||
let computedPropertyCount = 0;
|
||||
|
||||
for ( let prop of this.properties ) {
|
||||
if ( prop.type === 'SpreadProperty' ) spreadPropertyCount += 1;
|
||||
if ( prop.computed ) computedPropertyCount += 1;
|
||||
}
|
||||
|
||||
if ( spreadPropertyCount ) {
|
||||
// enclose run of non-spread properties in curlies
|
||||
let i = this.properties.length;
|
||||
while ( i-- ) {
|
||||
const prop = this.properties[i];
|
||||
|
||||
if ( prop.type === 'Property' ) {
|
||||
const lastProp = this.properties[ i - 1 ];
|
||||
const nextProp = this.properties[ i + 1 ];
|
||||
|
||||
if ( !lastProp || lastProp.type !== 'Property' ) {
|
||||
code.insertRight( prop.start, '{' );
|
||||
}
|
||||
|
||||
if ( !nextProp || nextProp.type !== 'Property' ) {
|
||||
code.insertLeft( prop.end, '}' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wrap the whole thing in Object.assign
|
||||
code.overwrite( this.start, this.properties[0].start, `${this.program.objectAssign}({}, `);
|
||||
code.overwrite( this.properties[ this.properties.length - 1 ].end, this.end, ')' );
|
||||
}
|
||||
|
||||
if ( computedPropertyCount && transforms.computedProperty ) {
|
||||
const i0 = this.getIndentation();
|
||||
|
||||
let isSimpleAssignment;
|
||||
let name;
|
||||
|
||||
let start;
|
||||
let end;
|
||||
|
||||
if ( this.parent.type === 'VariableDeclarator' && this.parent.parent.declarations.length === 1 ) {
|
||||
isSimpleAssignment = true;
|
||||
name = this.parent.id.alias || this.parent.id.name; // TODO is this right?
|
||||
} else if ( this.parent.type === 'AssignmentExpression' && this.parent.parent.type === 'ExpressionStatement' && this.parent.left.type === 'Identifier' ) {
|
||||
isSimpleAssignment = true;
|
||||
name = this.parent.left.alias || this.parent.left.name; // TODO is this right?
|
||||
}
|
||||
|
||||
// handle block scoping
|
||||
const declaration = this.findScope( false ).findDeclaration( name );
|
||||
if ( declaration ) name = declaration.name;
|
||||
|
||||
start = this.start + 1;
|
||||
end = this.end;
|
||||
|
||||
if ( isSimpleAssignment ) {
|
||||
// ???
|
||||
} else {
|
||||
name = this.findScope( true ).createIdentifier( 'obj' );
|
||||
|
||||
const statement = this.findNearest( /(?:Statement|Declaration)$/ );
|
||||
code.insertRight( statement.start, `var ${name};\n${i0}` );
|
||||
|
||||
code.insertRight( this.start, `( ${name} = ` );
|
||||
}
|
||||
|
||||
const len = this.properties.length;
|
||||
let lastComputedProp;
|
||||
|
||||
for ( let i = 0; i < len; i += 1 ) {
|
||||
const prop = this.properties[i];
|
||||
|
||||
if ( prop.computed ) {
|
||||
lastComputedProp = prop;
|
||||
let moveStart = i > 0 ? this.properties[ i - 1 ].end : start;
|
||||
|
||||
code.overwrite( moveStart, prop.start, isSimpleAssignment ? `;\n${i0}${name}` : `, ${name}` );
|
||||
let c = prop.key.end;
|
||||
while ( code.original[c] !== ']' ) c += 1;
|
||||
c += 1;
|
||||
|
||||
if ( prop.value.start > c ) code.remove( c, prop.value.start );
|
||||
code.insertLeft( c, ' = ' );
|
||||
code.move( moveStart, prop.end, end );
|
||||
|
||||
if ( i === 0 && len > 1 ) {
|
||||
// remove trailing comma
|
||||
c = prop.end;
|
||||
while ( code.original[c] !== ',' ) c += 1;
|
||||
|
||||
code.remove( prop.end, c + 1 );
|
||||
}
|
||||
|
||||
if ( prop.method && transforms.conciseMethodProperty ) {
|
||||
code.insertRight( prop.value.start, 'function ' );
|
||||
}
|
||||
|
||||
deindent( prop.value, code );
|
||||
}
|
||||
}
|
||||
|
||||
// special case
|
||||
if ( computedPropertyCount === len ) {
|
||||
code.remove( this.properties[ len - 1 ].end, this.end - 1 );
|
||||
}
|
||||
|
||||
if ( !isSimpleAssignment ) {
|
||||
code.insertLeft( lastComputedProp.end, `, ${name} )` );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
node_modules/buble/src/program/types/Property.js
generated
vendored
Normal file
23
node_modules/buble/src/program/types/Property.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import Node from '../Node.js';
|
||||
import reserved from '../../utils/reserved.js';
|
||||
|
||||
export default class Property extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.conciseMethodProperty && !this.computed && this.parent.type !== 'ObjectPattern' ) {
|
||||
if ( this.shorthand ) {
|
||||
code.insertRight( this.start, `${this.key.name}: ` );
|
||||
} else if ( this.method ) {
|
||||
const name = this.findScope( true ).createIdentifier( this.key.type === 'Identifier' ? this.key.name : this.key.value );
|
||||
if ( this.value.generator ) code.remove( this.start, this.key.start );
|
||||
code.insertLeft( this.key.end, `: function${this.value.generator ? '*' : ''} ${name}` );
|
||||
}
|
||||
}
|
||||
|
||||
if ( transforms.reservedProperties && reserved[ this.key.name ] ) {
|
||||
code.insertRight( this.key.start, `'` );
|
||||
code.insertLeft( this.key.end, `'` );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
27
node_modules/buble/src/program/types/ReturnStatement.js
generated
vendored
Normal file
27
node_modules/buble/src/program/types/ReturnStatement.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class ReturnStatement extends Node {
|
||||
initialise ( transforms ) {
|
||||
this.loop = this.findNearest( /(?:For(?:In)?|While)Statement/ );
|
||||
this.nearestFunction = this.findNearest( /Function/ );
|
||||
|
||||
if ( this.loop && ( !this.nearestFunction || this.loop.depth > this.nearestFunction.depth ) ) {
|
||||
this.loop.canReturn = true;
|
||||
this.shouldWrap = true;
|
||||
}
|
||||
|
||||
if ( this.argument ) this.argument.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.argument ) {
|
||||
const shouldWrap = this.shouldWrap && this.loop && this.loop.shouldRewriteAsFunction;
|
||||
|
||||
if ( shouldWrap ) code.insertRight( this.argument.start, `{ v: ` );
|
||||
|
||||
if ( this.argument ) this.argument.transpile( code, transforms );
|
||||
|
||||
if ( shouldWrap ) code.insertLeft( this.argument.end, ` }` );
|
||||
}
|
||||
}
|
||||
}
|
11
node_modules/buble/src/program/types/SpreadProperty.js
generated
vendored
Normal file
11
node_modules/buble/src/program/types/SpreadProperty.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import Node from '../Node.js';
|
||||
import reserved from '../../utils/reserved.js';
|
||||
|
||||
export default class SpreadProperty extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
code.remove( this.start, this.argument.start );
|
||||
code.remove( this.argument.end, this.end );
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
68
node_modules/buble/src/program/types/Super.js
generated
vendored
Normal file
68
node_modules/buble/src/program/types/Super.js
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class Super extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.classes ) {
|
||||
this.method = this.findNearest( 'MethodDefinition' );
|
||||
if ( !this.method ) throw new CompileError( this, 'use of super outside class method' );
|
||||
|
||||
const parentClass = this.findNearest( 'ClassBody' ).parent;
|
||||
this.superClassName = parentClass.superClass && (parentClass.superClass.name || 'superclass');
|
||||
|
||||
if ( !this.superClassName ) throw new CompileError( this, 'super used in base class' );
|
||||
|
||||
this.isCalled = this.parent.type === 'CallExpression' && this === this.parent.callee;
|
||||
|
||||
if ( this.method.kind !== 'constructor' && this.isCalled ) {
|
||||
throw new CompileError( this, 'super() not allowed outside class constructor' );
|
||||
}
|
||||
|
||||
this.isMember = this.parent.type === 'MemberExpression';
|
||||
|
||||
if ( !this.isCalled && !this.isMember ) {
|
||||
throw new CompileError( this, 'Unexpected use of `super` (expected `super(...)` or `super.*`)' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( transforms.arrow ) {
|
||||
const lexicalBoundary = this.findLexicalBoundary();
|
||||
const arrowFunction = this.findNearest( 'ArrowFunctionExpression' );
|
||||
const loop = this.findNearest( /(?:For(?:In|Of)?|While)Statement/ );
|
||||
|
||||
if ( arrowFunction && arrowFunction.depth > lexicalBoundary.depth ) {
|
||||
this.thisAlias = lexicalBoundary.getThisAlias();
|
||||
}
|
||||
|
||||
if ( loop && loop.body.contains( this ) && loop.depth > lexicalBoundary.depth ) {
|
||||
this.thisAlias = lexicalBoundary.getThisAlias();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.classes ) {
|
||||
const expression = ( this.isCalled || this.method.static ) ?
|
||||
this.superClassName :
|
||||
`${this.superClassName}.prototype`;
|
||||
|
||||
code.overwrite( this.start, this.end, expression, true );
|
||||
|
||||
const callExpression = this.isCalled ? this.parent : this.parent.parent;
|
||||
|
||||
if ( callExpression && callExpression.type === 'CallExpression' ) {
|
||||
if ( !this.noCall ) { // special case – `super( ...args )`
|
||||
code.insertLeft( callExpression.callee.end, '.call' );
|
||||
}
|
||||
|
||||
const thisAlias = this.thisAlias || 'this';
|
||||
|
||||
if ( callExpression.arguments.length ) {
|
||||
code.insertLeft( callExpression.arguments[0].start, `${thisAlias}, ` );
|
||||
} else {
|
||||
code.insertLeft( callExpression.end - 1, `${thisAlias}` );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
37
node_modules/buble/src/program/types/TaggedTemplateExpression.js
generated
vendored
Normal file
37
node_modules/buble/src/program/types/TaggedTemplateExpression.js
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class TaggedTemplateExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.templateString && !transforms.dangerousTaggedTemplateString ) {
|
||||
throw new CompileError( this, 'Tagged template strings are not supported. Use `transforms: { templateString: false }` to skip transformation and disable this error, or `transforms: { dangerousTaggedTemplateString: true }` if you know what you\'re doing' );
|
||||
}
|
||||
|
||||
super.initialise( transforms );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.templateString && transforms.dangerousTaggedTemplateString ) {
|
||||
const ordered = this.quasi.expressions.concat( this.quasi.quasis ).sort( ( a, b ) => a.start - b.start );
|
||||
|
||||
// insert strings at start
|
||||
const templateStrings = this.quasi.quasis.map( quasi => JSON.stringify( quasi.value.cooked ) );
|
||||
code.overwrite( this.tag.end, ordered[0].start, `([${templateStrings.join(', ')}]` );
|
||||
|
||||
let lastIndex = ordered[0].start;
|
||||
ordered.forEach( node => {
|
||||
if ( node.type === 'TemplateElement' ) {
|
||||
code.remove( lastIndex, node.end );
|
||||
} else {
|
||||
code.overwrite( lastIndex, node.start, ', ' );
|
||||
}
|
||||
|
||||
lastIndex = node.end;
|
||||
});
|
||||
|
||||
code.overwrite( lastIndex, this.end, ')' );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
7
node_modules/buble/src/program/types/TemplateElement.js
generated
vendored
Normal file
7
node_modules/buble/src/program/types/TemplateElement.js
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class TemplateElement extends Node {
|
||||
initialise ( transforms ) {
|
||||
this.program.templateElements.push( this );
|
||||
}
|
||||
}
|
69
node_modules/buble/src/program/types/TemplateLiteral.js
generated
vendored
Normal file
69
node_modules/buble/src/program/types/TemplateLiteral.js
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class TemplateLiteral extends Node {
|
||||
transpile ( code, transforms ) {
|
||||
if ( transforms.templateString && this.parent.type !== 'TaggedTemplateExpression' ) {
|
||||
let ordered = this.expressions.concat( this.quasis )
|
||||
.sort( ( a, b ) => a.start - b.start || a.end - b.end )
|
||||
.filter( ( node, i ) => {
|
||||
// include all expressions
|
||||
if ( node.type !== 'TemplateElement' ) return true;
|
||||
|
||||
// include all non-empty strings
|
||||
if ( node.value.raw ) return true;
|
||||
|
||||
// exclude all empty strings not at the head
|
||||
return !i;
|
||||
});
|
||||
|
||||
// special case – we may be able to skip the first element,
|
||||
// if it's the empty string, but only if the second and
|
||||
// third elements aren't both expressions (since they maybe
|
||||
// be numeric, and `1 + 2 + '3' === '33'`)
|
||||
if ( ordered.length >= 3 ) {
|
||||
const [ first, , third ] = ordered;
|
||||
if ( first.type === 'TemplateElement' && first.value.raw === '' && third.type === 'TemplateElement' ) {
|
||||
ordered.shift();
|
||||
}
|
||||
}
|
||||
|
||||
const parenthesise = ( this.quasis.length !== 1 || this.expressions.length !== 0 ) &&
|
||||
this.parent.type !== 'AssignmentExpression' &&
|
||||
this.parent.type !== 'VariableDeclarator' &&
|
||||
( this.parent.type !== 'BinaryExpression' || this.parent.operator !== '+' );
|
||||
|
||||
if ( parenthesise ) code.insertRight( this.start, '(' );
|
||||
|
||||
let lastIndex = this.start;
|
||||
|
||||
ordered.forEach( ( node, i ) => {
|
||||
if ( node.type === 'TemplateElement' ) {
|
||||
let replacement = '';
|
||||
if ( i ) replacement += ' + ';
|
||||
replacement += JSON.stringify( node.value.cooked );
|
||||
|
||||
code.overwrite( lastIndex, node.end, replacement );
|
||||
} else {
|
||||
const parenthesise = node.type !== 'Identifier'; // TODO other cases where it's safe
|
||||
|
||||
let replacement = '';
|
||||
if ( i ) replacement += ' + ';
|
||||
if ( parenthesise ) replacement += '(';
|
||||
|
||||
code.overwrite( lastIndex, node.start, replacement );
|
||||
|
||||
if ( parenthesise ) code.insertLeft( node.end, ')' );
|
||||
}
|
||||
|
||||
lastIndex = node.end;
|
||||
});
|
||||
|
||||
let close = '';
|
||||
if ( parenthesise ) close += ')';
|
||||
|
||||
code.overwrite( lastIndex, this.end, close );
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
25
node_modules/buble/src/program/types/ThisExpression.js
generated
vendored
Normal file
25
node_modules/buble/src/program/types/ThisExpression.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import Node from '../Node.js';
|
||||
|
||||
export default class ThisExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.arrow ) {
|
||||
const lexicalBoundary = this.findLexicalBoundary();
|
||||
const arrowFunction = this.findNearest( 'ArrowFunctionExpression' );
|
||||
const loop = this.findNearest( /(?:For(?:In|Of)?|While)Statement/ );
|
||||
|
||||
if ( arrowFunction && arrowFunction.depth > lexicalBoundary.depth ) {
|
||||
this.alias = lexicalBoundary.getThisAlias();
|
||||
}
|
||||
|
||||
if ( loop && loop.body.contains( this ) && loop.depth > lexicalBoundary.depth ) {
|
||||
this.alias = lexicalBoundary.getThisAlias();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.alias ) {
|
||||
code.overwrite( this.start, this.end, this.alias, true );
|
||||
}
|
||||
}
|
||||
}
|
15
node_modules/buble/src/program/types/UpdateExpression.js
generated
vendored
Normal file
15
node_modules/buble/src/program/types/UpdateExpression.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class UpdateExpression extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( this.argument.type === 'Identifier' ) {
|
||||
const declaration = this.findScope( false ).findDeclaration( this.argument.name );
|
||||
if ( declaration && declaration.kind === 'const' ) {
|
||||
throw new CompileError( this, `${this.argument.name} is read-only` );
|
||||
}
|
||||
}
|
||||
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
85
node_modules/buble/src/program/types/VariableDeclaration.js
generated
vendored
Normal file
85
node_modules/buble/src/program/types/VariableDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
import Node from '../Node.js';
|
||||
import destructure from '../../utils/destructure.js';
|
||||
|
||||
export default class VariableDeclaration extends Node {
|
||||
initialise ( transforms ) {
|
||||
this.scope = this.findScope( this.kind === 'var' );
|
||||
this.declarations.forEach( declarator => declarator.initialise( transforms ) );
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
const i0 = this.getIndentation();
|
||||
let kind = this.kind;
|
||||
|
||||
if ( transforms.letConst && kind !== 'var' ) {
|
||||
kind = 'var';
|
||||
code.overwrite( this.start, this.start + this.kind.length, kind, true );
|
||||
}
|
||||
|
||||
if ( transforms.destructuring ) {
|
||||
let c = this.start;
|
||||
let lastDeclaratorIsPattern;
|
||||
|
||||
this.declarations.forEach( ( declarator, i ) => {
|
||||
if ( declarator.id.type === 'Identifier' ) {
|
||||
if ( i > 0 && this.declarations[ i - 1 ].id.type !== 'Identifier' ) {
|
||||
code.overwrite( c, declarator.id.start, `var ` );
|
||||
}
|
||||
} else {
|
||||
if ( i === 0 ) {
|
||||
code.remove( c, declarator.id.start );
|
||||
} else {
|
||||
code.overwrite( c, declarator.id.start, `;\n${i0}` );
|
||||
}
|
||||
|
||||
const simple = declarator.init.type === 'Identifier' && !declarator.init.rewritten;
|
||||
|
||||
const name = simple ? declarator.init.name : declarator.findScope( true ).createIdentifier( 'ref' );
|
||||
|
||||
let c = declarator.start;
|
||||
|
||||
let statementGenerators = [];
|
||||
|
||||
if ( simple ) {
|
||||
code.remove( declarator.id.end, declarator.end );
|
||||
} else {
|
||||
statementGenerators.push( ( start, prefix, suffix ) => {
|
||||
code.insertRight( declarator.id.end, `var ${name}` );
|
||||
code.insertLeft( declarator.init.end, `;${suffix}` );
|
||||
code.move( declarator.id.end, declarator.end, start );
|
||||
});
|
||||
}
|
||||
|
||||
destructure( code, declarator.findScope( false ), declarator.id, name, statementGenerators );
|
||||
|
||||
let suffix = `\n${i0}`;
|
||||
statementGenerators.forEach( ( fn, j ) => {
|
||||
if ( i === this.declarations.length - 1 && j === statementGenerators.length - 1 ) {
|
||||
suffix = '';
|
||||
}
|
||||
|
||||
fn( declarator.start, '', suffix );
|
||||
});
|
||||
}
|
||||
|
||||
if ( declarator.init ) {
|
||||
declarator.init.transpile( code, transforms );
|
||||
}
|
||||
|
||||
c = declarator.end;
|
||||
lastDeclaratorIsPattern = declarator.id.type !== 'Identifier';
|
||||
});
|
||||
|
||||
if ( lastDeclaratorIsPattern ) {
|
||||
code.remove( c, this.end );
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
this.declarations.forEach( declarator => {
|
||||
if ( declarator.init ) declarator.init.transpile( code, transforms );
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
14
node_modules/buble/src/program/types/VariableDeclarator.js
generated
vendored
Normal file
14
node_modules/buble/src/program/types/VariableDeclarator.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import Node from '../Node.js';
|
||||
import CompileError from '../../utils/CompileError.js';
|
||||
|
||||
export default class VariableDeclarator extends Node {
|
||||
initialise ( transforms ) {
|
||||
let kind = this.parent.kind;
|
||||
if ( kind === 'let' && this.parent.parent.type === 'ForStatement' ) {
|
||||
kind = 'for.let'; // special case...
|
||||
}
|
||||
|
||||
this.parent.scope.addDeclaration( this.id, kind );
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
88
node_modules/buble/src/program/types/index.js
generated
vendored
Normal file
88
node_modules/buble/src/program/types/index.js
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
import ArrayExpression from './ArrayExpression.js';
|
||||
import ArrowFunctionExpression from './ArrowFunctionExpression.js';
|
||||
import AssignmentExpression from './AssignmentExpression.js';
|
||||
import BinaryExpression from './BinaryExpression.js';
|
||||
import BreakStatement from './BreakStatement.js';
|
||||
import CallExpression from './CallExpression.js';
|
||||
import ClassBody from './ClassBody.js';
|
||||
import ClassDeclaration from './ClassDeclaration.js';
|
||||
import ClassExpression from './ClassExpression.js';
|
||||
import ContinueStatement from './ContinueStatement.js';
|
||||
import ExportDefaultDeclaration from './ExportDefaultDeclaration.js';
|
||||
import ExportNamedDeclaration from './ExportNamedDeclaration.js';
|
||||
import ForStatement from './ForStatement.js';
|
||||
import ForInStatement from './ForInStatement.js';
|
||||
import ForOfStatement from './ForOfStatement.js';
|
||||
import FunctionDeclaration from './FunctionDeclaration.js';
|
||||
import FunctionExpression from './FunctionExpression.js';
|
||||
import Identifier from './Identifier.js';
|
||||
import ImportDeclaration from './ImportDeclaration.js';
|
||||
import ImportDefaultSpecifier from './ImportDefaultSpecifier.js';
|
||||
import ImportSpecifier from './ImportSpecifier.js';
|
||||
import JSXAttribute from './JSXAttribute.js';
|
||||
import JSXClosingElement from './JSXClosingElement.js';
|
||||
import JSXElement from './JSXElement.js';
|
||||
import JSXExpressionContainer from './JSXExpressionContainer.js';
|
||||
import JSXOpeningElement from './JSXOpeningElement.js';
|
||||
import JSXSpreadAttribute from './JSXSpreadAttribute.js';
|
||||
import Literal from './Literal.js';
|
||||
import LoopStatement from './shared/LoopStatement.js';
|
||||
import MemberExpression from './MemberExpression.js';
|
||||
import ObjectExpression from './ObjectExpression.js';
|
||||
import Property from './Property.js';
|
||||
import ReturnStatement from './ReturnStatement.js';
|
||||
import SpreadProperty from './SpreadProperty.js';
|
||||
import Super from './Super.js';
|
||||
import TaggedTemplateExpression from './TaggedTemplateExpression.js';
|
||||
import TemplateElement from './TemplateElement.js';
|
||||
import TemplateLiteral from './TemplateLiteral.js';
|
||||
import ThisExpression from './ThisExpression.js';
|
||||
import UpdateExpression from './UpdateExpression.js';
|
||||
import VariableDeclaration from './VariableDeclaration.js';
|
||||
import VariableDeclarator from './VariableDeclarator.js';
|
||||
|
||||
export default {
|
||||
ArrayExpression,
|
||||
ArrowFunctionExpression,
|
||||
AssignmentExpression,
|
||||
BinaryExpression,
|
||||
BreakStatement,
|
||||
CallExpression,
|
||||
ClassBody,
|
||||
ClassDeclaration,
|
||||
ClassExpression,
|
||||
ContinueStatement,
|
||||
DoWhileStatement: LoopStatement,
|
||||
ExportNamedDeclaration,
|
||||
ExportDefaultDeclaration,
|
||||
ForStatement,
|
||||
ForInStatement,
|
||||
ForOfStatement,
|
||||
FunctionDeclaration,
|
||||
FunctionExpression,
|
||||
Identifier,
|
||||
ImportDeclaration,
|
||||
ImportDefaultSpecifier,
|
||||
ImportSpecifier,
|
||||
JSXAttribute,
|
||||
JSXClosingElement,
|
||||
JSXElement,
|
||||
JSXExpressionContainer,
|
||||
JSXOpeningElement,
|
||||
JSXSpreadAttribute,
|
||||
Literal,
|
||||
MemberExpression,
|
||||
ObjectExpression,
|
||||
Property,
|
||||
ReturnStatement,
|
||||
SpreadProperty,
|
||||
Super,
|
||||
TaggedTemplateExpression,
|
||||
TemplateElement,
|
||||
TemplateLiteral,
|
||||
ThisExpression,
|
||||
UpdateExpression,
|
||||
VariableDeclaration,
|
||||
VariableDeclarator,
|
||||
WhileStatement: LoopStatement
|
||||
};
|
85
node_modules/buble/src/program/types/shared/LoopStatement.js
generated
vendored
Normal file
85
node_modules/buble/src/program/types/shared/LoopStatement.js
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
import Node from '../../Node.js';
|
||||
import extractNames from '../../extractNames.js';
|
||||
|
||||
export default class LoopStatement extends Node {
|
||||
findScope ( functionScope ) {
|
||||
return functionScope || !this.createdScope ? this.parent.findScope( functionScope ) : this.body.scope;
|
||||
}
|
||||
|
||||
initialise ( transforms ) {
|
||||
this.body.createScope();
|
||||
this.createdScope = true;
|
||||
|
||||
// this is populated as and when reassignments occur
|
||||
this.reassigned = Object.create( null );
|
||||
this.aliases = Object.create( null );
|
||||
|
||||
super.initialise( transforms );
|
||||
|
||||
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 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 ( this.shouldRewriteAsFunction ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transpile ( code, transforms ) {
|
||||
if ( this.shouldRewriteAsFunction ) {
|
||||
const i0 = this.getIndentation();
|
||||
const i1 = i0 + code.getIndentString();
|
||||
|
||||
const argString = this.args ? ` ${this.args.join( ', ' )} ` : '';
|
||||
const paramString = this.params ? ` ${this.params.join( ', ' )} ` : '';
|
||||
|
||||
const functionScope = this.findScope( true );
|
||||
const loop = functionScope.createIdentifier( 'loop' );
|
||||
|
||||
const before = `var ${loop} = function (${paramString}) ` + ( this.body.synthetic ? `{\n${i0}${code.getIndentString()}` : '' );
|
||||
const after = ( this.body.synthetic ? `\n${i0}}` : '' ) + `;\n\n${i0}`;
|
||||
|
||||
code.insertRight( this.body.start, before );
|
||||
code.insertLeft( this.body.end, after );
|
||||
code.move( this.start, this.body.start, this.body.end );
|
||||
|
||||
if ( this.canBreak || this.canReturn ) {
|
||||
const returned = functionScope.createIdentifier( 'returned' );
|
||||
|
||||
let insert = `{\n${i1}var ${returned} = ${loop}(${argString});\n`;
|
||||
if ( this.canBreak ) insert += `\n${i1}if ( ${returned} === 'break' ) break;`;
|
||||
if ( this.canReturn ) insert += `\n${i1}if ( ${returned} ) return returned.v;`;
|
||||
insert += `\n${i0}}`;
|
||||
|
||||
code.insertRight( this.body.end, insert );
|
||||
} else {
|
||||
const callExpression = `${loop}(${argString});`;
|
||||
|
||||
if ( this.type === 'DoWhileStatement' ) {
|
||||
code.overwrite( this.start, this.body.start, `do {\n${i1}${callExpression}\n${i0}}` );
|
||||
} else {
|
||||
code.insertRight( this.body.end, callExpression );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.transpile( code, transforms );
|
||||
}
|
||||
}
|
9
node_modules/buble/src/program/types/shared/ModuleDeclaration.js
generated
vendored
Normal file
9
node_modules/buble/src/program/types/shared/ModuleDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import Node from '../../Node.js';
|
||||
import CompileError from '../../../utils/CompileError.js';
|
||||
|
||||
export default class ModuleDeclaration extends Node {
|
||||
initialise ( transforms ) {
|
||||
if ( transforms.moduleImport ) throw new CompileError( this, 'Modules are not supported' );
|
||||
super.initialise( transforms );
|
||||
}
|
||||
}
|
54
node_modules/buble/src/program/wrap.js
generated
vendored
Normal file
54
node_modules/buble/src/program/wrap.js
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
import types from './types/index.js';
|
||||
import BlockStatement from './BlockStatement.js';
|
||||
import Node from './Node.js';
|
||||
import keys from './keys.js';
|
||||
|
||||
const statementsWithBlocks = {
|
||||
IfStatement: 'consequent',
|
||||
ForStatement: 'body',
|
||||
ForInStatement: 'body',
|
||||
ForOfStatement: 'body',
|
||||
WhileStatement: 'body',
|
||||
DoWhileStatement: 'body',
|
||||
ArrowFunctionExpression: 'body'
|
||||
};
|
||||
|
||||
export default function wrap ( raw, parent ) {
|
||||
if ( !raw ) return;
|
||||
|
||||
if ( 'length' in raw ) {
|
||||
let i = raw.length;
|
||||
while ( i-- ) wrap( raw[i], parent );
|
||||
return;
|
||||
}
|
||||
|
||||
// with e.g. shorthand properties, key and value are
|
||||
// the same node. We don't want to wrap an object twice
|
||||
if ( raw.__wrapped ) return;
|
||||
raw.__wrapped = true;
|
||||
|
||||
if ( !keys[ raw.type ] ) {
|
||||
keys[ raw.type ] = Object.keys( raw ).filter( key => typeof raw[ key ] === 'object' );
|
||||
}
|
||||
|
||||
// special case – body-less if/for/while statements. TODO others?
|
||||
const bodyType = statementsWithBlocks[ raw.type ];
|
||||
if ( bodyType && raw[ bodyType ].type !== 'BlockStatement' ) {
|
||||
const expression = raw[ bodyType ];
|
||||
|
||||
// create a synthetic block statement, otherwise all hell
|
||||
// breaks loose when it comes to block scoping
|
||||
raw[ bodyType ] = {
|
||||
start: expression.start,
|
||||
end: expression.end,
|
||||
type: 'BlockStatement',
|
||||
body: [ expression ],
|
||||
synthetic: true
|
||||
};
|
||||
}
|
||||
|
||||
Node( raw, parent );
|
||||
|
||||
const type = ( raw.type === 'BlockStatement' ? BlockStatement : types[ raw.type ] ) || Node;
|
||||
raw.__proto__ = type.prototype;
|
||||
}
|
Reference in New Issue
Block a user