2013-12-16 22:19:36 +00:00
/ * *
2014-01-03 15:54:38 +00:00
* JSXTransformer v0 . 8.0
2013-12-16 22:19:36 +00:00
* /
2014-01-03 15:54:38 +00:00
! function ( e ) { "object" == typeof exports ? module . exports = e ( ) : "function" == typeof define && define . amd ? define ( e ) : "undefined" != typeof window ? window . JSXTransformer = e ( ) : "undefined" != typeof global ? global . JSXTransformer = e ( ) : "undefined" != typeof self && ( self . JSXTransformer = e ( ) ) } ( function ( ) { var define , module , exports ; return ( function e ( t , n , r ) { function s ( o , u ) { if ( ! n [ o ] ) { if ( ! t [ o ] ) { var a = typeof require == "function" && require ; if ( ! u && a ) return a ( o , ! 0 ) ; if ( i ) return i ( o , ! 0 ) ; throw new Error ( "Cannot find module '" + o + "'" ) } var f = n [ o ] = { exports : { } } ; t [ o ] [ 0 ] . call ( f . exports , function ( e ) { var n = t [ o ] [ 1 ] [ e ] ; return s ( n ? n : e ) } , f , f . exports , e , t , n , r ) } return n [ o ] . exports } var i = typeof require == "function" && require ; for ( var o = 0 ; o < r . length ; o ++ ) s ( r [ o ] ) ; return s } ) ( { 1 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
//
// The shims in this file are not fully implemented shims for the ES5
// features, but do work for the particular usecases there is in
// the other modules.
//
var toString = Object . prototype . toString ;
var hasOwnProperty = Object . prototype . hasOwnProperty ;
// Array.isArray is supported in IE9
function isArray ( xs ) {
return toString . call ( xs ) === '[object Array]' ;
}
exports . isArray = typeof Array . isArray === 'function' ? Array . isArray : isArray ;
// Array.prototype.indexOf is supported in IE9
exports . indexOf = function indexOf ( xs , x ) {
if ( xs . indexOf ) return xs . indexOf ( x ) ;
for ( var i = 0 ; i < xs . length ; i ++ ) {
if ( x === xs [ i ] ) return i ;
}
return - 1 ;
} ;
// Array.prototype.filter is supported in IE9
exports . filter = function filter ( xs , fn ) {
if ( xs . filter ) return xs . filter ( fn ) ;
var res = [ ] ;
for ( var i = 0 ; i < xs . length ; i ++ ) {
if ( fn ( xs [ i ] , i , xs ) ) res . push ( xs [ i ] ) ;
}
return res ;
} ;
// Array.prototype.forEach is supported in IE9
exports . forEach = function forEach ( xs , fn , self ) {
if ( xs . forEach ) return xs . forEach ( fn , self ) ;
for ( var i = 0 ; i < xs . length ; i ++ ) {
fn . call ( self , xs [ i ] , i , xs ) ;
}
} ;
// Array.prototype.map is supported in IE9
exports . map = function map ( xs , fn ) {
if ( xs . map ) return xs . map ( fn ) ;
var out = new Array ( xs . length ) ;
for ( var i = 0 ; i < xs . length ; i ++ ) {
out [ i ] = fn ( xs [ i ] , i , xs ) ;
}
return out ;
} ;
// Array.prototype.reduce is supported in IE9
exports . reduce = function reduce ( array , callback , opt _initialValue ) {
if ( array . reduce ) return array . reduce ( callback , opt _initialValue ) ;
var value , isValueSet = false ;
if ( 2 < arguments . length ) {
value = opt _initialValue ;
isValueSet = true ;
}
for ( var i = 0 , l = array . length ; l > i ; ++ i ) {
if ( array . hasOwnProperty ( i ) ) {
if ( isValueSet ) {
value = callback ( value , array [ i ] , i , array ) ;
}
else {
value = array [ i ] ;
isValueSet = true ;
}
}
}
return value ;
} ;
// String.prototype.substr - negative index don't work in IE8
if ( 'ab' . substr ( - 1 ) !== 'b' ) {
exports . substr = function ( str , start , length ) {
// did we get a negative start, calculate how much it is from the beginning of the string
if ( start < 0 ) start = str . length + start ;
// call the original function
return str . substr ( start , length ) ;
} ;
} else {
exports . substr = function ( str , start , length ) {
return str . substr ( start , length ) ;
} ;
}
// String.prototype.trim is supported in IE9
exports . trim = function ( str ) {
if ( str . trim ) return str . trim ( ) ;
return str . replace ( /^\s+|\s+$/g , '' ) ;
} ;
// Function.prototype.bind is supported in IE9
exports . bind = function ( ) {
var args = Array . prototype . slice . call ( arguments ) ;
var fn = args . shift ( ) ;
if ( fn . bind ) return fn . bind . apply ( fn , args ) ;
var self = args . shift ( ) ;
return function ( ) {
fn . apply ( self , args . concat ( [ Array . prototype . slice . call ( arguments ) ] ) ) ;
} ;
} ;
// Object.create is supported in IE9
function create ( prototype , properties ) {
var object ;
if ( prototype === null ) {
object = { '__proto__' : null } ;
}
else {
if ( typeof prototype !== 'object' ) {
throw new TypeError (
'typeof prototype[' + ( typeof prototype ) + '] != \'object\''
) ;
}
var Type = function ( ) { } ;
Type . prototype = prototype ;
object = new Type ( ) ;
object . _ _proto _ _ = prototype ;
}
if ( typeof properties !== 'undefined' && Object . defineProperties ) {
Object . defineProperties ( object , properties ) ;
}
return object ;
}
exports . create = typeof Object . create === 'function' ? Object . create : create ;
// Object.keys and Object.getOwnPropertyNames is supported in IE9 however
// they do show a description and number property on Error objects
function notObject ( object ) {
return ( ( typeof object != "object" && typeof object != "function" ) || object === null ) ;
}
function keysShim ( object ) {
if ( notObject ( object ) ) {
throw new TypeError ( "Object.keys called on a non-object" ) ;
}
var result = [ ] ;
for ( var name in object ) {
if ( hasOwnProperty . call ( object , name ) ) {
result . push ( name ) ;
}
}
return result ;
}
// getOwnPropertyNames is almost the same as Object.keys one key feature
// is that it returns hidden properties, since that can't be implemented,
// this feature gets reduced so it just shows the length property on arrays
function propertyShim ( object ) {
if ( notObject ( object ) ) {
throw new TypeError ( "Object.getOwnPropertyNames called on a non-object" ) ;
}
var result = keysShim ( object ) ;
if ( exports . isArray ( object ) && exports . indexOf ( object , 'length' ) === - 1 ) {
result . push ( 'length' ) ;
}
return result ;
}
var keys = typeof Object . keys === 'function' ? Object . keys : keysShim ;
var getOwnPropertyNames = typeof Object . getOwnPropertyNames === 'function' ?
Object . getOwnPropertyNames : propertyShim ;
if ( new Error ( ) . hasOwnProperty ( 'description' ) ) {
var ERROR _PROPERTY _FILTER = function ( obj , array ) {
if ( toString . call ( obj ) === '[object Error]' ) {
array = exports . filter ( array , function ( name ) {
return name !== 'description' && name !== 'number' && name !== 'message' ;
} ) ;
}
return array ;
} ;
exports . keys = function ( object ) {
return ERROR _PROPERTY _FILTER ( object , keys ( object ) ) ;
} ;
exports . getOwnPropertyNames = function ( object ) {
return ERROR _PROPERTY _FILTER ( object , getOwnPropertyNames ( object ) ) ;
} ;
} else {
exports . keys = keys ;
exports . getOwnPropertyNames = getOwnPropertyNames ;
}
// Object.getOwnPropertyDescriptor - supported in IE8 but only on dom elements
function valueObject ( value , key ) {
return { value : value [ key ] } ;
}
if ( typeof Object . getOwnPropertyDescriptor === 'function' ) {
try {
Object . getOwnPropertyDescriptor ( { 'a' : 1 } , 'a' ) ;
exports . getOwnPropertyDescriptor = Object . getOwnPropertyDescriptor ;
} catch ( e ) {
// IE8 dom element issue - use a try catch and default to valueObject
exports . getOwnPropertyDescriptor = function ( value , key ) {
try {
return Object . getOwnPropertyDescriptor ( value , key ) ;
} catch ( e ) {
return valueObject ( value , key ) ;
}
} ;
}
} else {
exports . getOwnPropertyDescriptor = valueObject ;
}
} , { } ] , 2 : [ function ( require , module , exports ) {
var process = require ( "__browserify_process" ) ; // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var util = require ( 'util' ) ;
var shims = require ( '_shims' ) ;
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray ( parts , allowAboveRoot ) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0 ;
for ( var i = parts . length - 1 ; i >= 0 ; i -- ) {
var last = parts [ i ] ;
if ( last === '.' ) {
parts . splice ( i , 1 ) ;
} else if ( last === '..' ) {
parts . splice ( i , 1 ) ;
up ++ ;
} else if ( up ) {
parts . splice ( i , 1 ) ;
up -- ;
}
}
// if the path is allowed to go above the root, restore leading ..s
if ( allowAboveRoot ) {
for ( ; up -- ; up ) {
parts . unshift ( '..' ) ;
}
}
return parts ;
}
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/ ;
var splitPath = function ( filename ) {
return splitPathRe . exec ( filename ) . slice ( 1 ) ;
} ;
// path.resolve([from ...], to)
// posix version
exports . resolve = function ( ) {
var resolvedPath = '' ,
resolvedAbsolute = false ;
for ( var i = arguments . length - 1 ; i >= - 1 && ! resolvedAbsolute ; i -- ) {
var path = ( i >= 0 ) ? arguments [ i ] : process . cwd ( ) ;
// Skip empty and invalid entries
if ( ! util . isString ( path ) ) {
throw new TypeError ( 'Arguments to path.resolve must be strings' ) ;
} else if ( ! path ) {
continue ;
}
resolvedPath = path + '/' + resolvedPath ;
resolvedAbsolute = path . charAt ( 0 ) === '/' ;
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray ( shims . filter ( resolvedPath . split ( '/' ) , function ( p ) {
return ! ! p ;
} ) , ! resolvedAbsolute ) . join ( '/' ) ;
return ( ( resolvedAbsolute ? '/' : '' ) + resolvedPath ) || '.' ;
} ;
// path.normalize(path)
// posix version
exports . normalize = function ( path ) {
var isAbsolute = exports . isAbsolute ( path ) ,
trailingSlash = shims . substr ( path , - 1 ) === '/' ;
// Normalize the path
path = normalizeArray ( shims . filter ( path . split ( '/' ) , function ( p ) {
return ! ! p ;
} ) , ! isAbsolute ) . join ( '/' ) ;
if ( ! path && ! isAbsolute ) {
path = '.' ;
}
if ( path && trailingSlash ) {
path += '/' ;
}
return ( isAbsolute ? '/' : '' ) + path ;
} ;
// posix version
exports . isAbsolute = function ( path ) {
return path . charAt ( 0 ) === '/' ;
} ;
// posix version
exports . join = function ( ) {
var paths = Array . prototype . slice . call ( arguments , 0 ) ;
return exports . normalize ( shims . filter ( paths , function ( p , index ) {
if ( ! util . isString ( p ) ) {
throw new TypeError ( 'Arguments to path.join must be strings' ) ;
}
return p ;
} ) . join ( '/' ) ) ;
} ;
// path.relative(from, to)
// posix version
exports . relative = function ( from , to ) {
from = exports . resolve ( from ) . substr ( 1 ) ;
to = exports . resolve ( to ) . substr ( 1 ) ;
function trim ( arr ) {
var start = 0 ;
for ( ; start < arr . length ; start ++ ) {
if ( arr [ start ] !== '' ) break ;
}
var end = arr . length - 1 ;
for ( ; end >= 0 ; end -- ) {
if ( arr [ end ] !== '' ) break ;
}
if ( start > end ) return [ ] ;
return arr . slice ( start , end - start + 1 ) ;
}
var fromParts = trim ( from . split ( '/' ) ) ;
var toParts = trim ( to . split ( '/' ) ) ;
var length = Math . min ( fromParts . length , toParts . length ) ;
var samePartsLength = length ;
for ( var i = 0 ; i < length ; i ++ ) {
if ( fromParts [ i ] !== toParts [ i ] ) {
samePartsLength = i ;
break ;
}
}
var outputParts = [ ] ;
for ( var i = samePartsLength ; i < fromParts . length ; i ++ ) {
outputParts . push ( '..' ) ;
}
outputParts = outputParts . concat ( toParts . slice ( samePartsLength ) ) ;
return outputParts . join ( '/' ) ;
} ;
exports . sep = '/' ;
exports . delimiter = ':' ;
exports . dirname = function ( path ) {
var result = splitPath ( path ) ,
root = result [ 0 ] ,
dir = result [ 1 ] ;
if ( ! root && ! dir ) {
// No dirname whatsoever
return '.' ;
}
if ( dir ) {
// It has a dirname, strip trailing slash
dir = dir . substr ( 0 , dir . length - 1 ) ;
}
return root + dir ;
} ;
exports . basename = function ( path , ext ) {
var f = splitPath ( path ) [ 2 ] ;
// TODO: make this comparison case-insensitive on windows?
if ( ext && f . substr ( - 1 * ext . length ) === ext ) {
f = f . substr ( 0 , f . length - ext . length ) ;
}
return f ;
} ;
exports . extname = function ( path ) {
return splitPath ( path ) [ 3 ] ;
} ;
2014-01-03 15:54:38 +00:00
} , { "__browserify_process" : 4 , "_shims" : 1 , "util" : 3 } ] , 3 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var shims = require ( '_shims' ) ;
var formatRegExp = /%[sdj%]/g ;
exports . format = function ( f ) {
if ( ! isString ( f ) ) {
var objects = [ ] ;
for ( var i = 0 ; i < arguments . length ; i ++ ) {
objects . push ( inspect ( arguments [ i ] ) ) ;
}
return objects . join ( ' ' ) ;
}
var i = 1 ;
var args = arguments ;
var len = args . length ;
var str = String ( f ) . replace ( formatRegExp , function ( x ) {
if ( x === '%%' ) return '%' ;
if ( i >= len ) return x ;
switch ( x ) {
case '%s' : return String ( args [ i ++ ] ) ;
case '%d' : return Number ( args [ i ++ ] ) ;
case '%j' :
try {
return JSON . stringify ( args [ i ++ ] ) ;
} catch ( _ ) {
return '[Circular]' ;
}
default :
return x ;
}
} ) ;
for ( var x = args [ i ] ; i < len ; x = args [ ++ i ] ) {
if ( isNull ( x ) || ! isObject ( x ) ) {
str += ' ' + x ;
} else {
str += ' ' + inspect ( x ) ;
}
}
return str ;
} ;
/ * *
* Echos the value of a value . Trys to print the value out
* in the best way possible given the different types .
*
* @ param { Object } obj The object to print out .
* @ param { Object } opts Optional options object that alters the output .
* /
/* legacy: obj, showHidden, depth, colors*/
function inspect ( obj , opts ) {
// default options
var ctx = {
seen : [ ] ,
stylize : stylizeNoColor
} ;
// legacy...
if ( arguments . length >= 3 ) ctx . depth = arguments [ 2 ] ;
if ( arguments . length >= 4 ) ctx . colors = arguments [ 3 ] ;
if ( isBoolean ( opts ) ) {
// legacy...
ctx . showHidden = opts ;
} else if ( opts ) {
// got an "options" object
exports . _extend ( ctx , opts ) ;
}
// set default options
if ( isUndefined ( ctx . showHidden ) ) ctx . showHidden = false ;
if ( isUndefined ( ctx . depth ) ) ctx . depth = 2 ;
if ( isUndefined ( ctx . colors ) ) ctx . colors = false ;
if ( isUndefined ( ctx . customInspect ) ) ctx . customInspect = true ;
if ( ctx . colors ) ctx . stylize = stylizeWithColor ;
return formatValue ( ctx , obj , ctx . depth ) ;
}
exports . inspect = inspect ;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect . colors = {
'bold' : [ 1 , 22 ] ,
'italic' : [ 3 , 23 ] ,
'underline' : [ 4 , 24 ] ,
'inverse' : [ 7 , 27 ] ,
'white' : [ 37 , 39 ] ,
'grey' : [ 90 , 39 ] ,
'black' : [ 30 , 39 ] ,
'blue' : [ 34 , 39 ] ,
'cyan' : [ 36 , 39 ] ,
'green' : [ 32 , 39 ] ,
'magenta' : [ 35 , 39 ] ,
'red' : [ 31 , 39 ] ,
'yellow' : [ 33 , 39 ]
} ;
// Don't use 'blue' not visible on cmd.exe
inspect . styles = {
'special' : 'cyan' ,
'number' : 'yellow' ,
'boolean' : 'yellow' ,
'undefined' : 'grey' ,
'null' : 'bold' ,
'string' : 'green' ,
'date' : 'magenta' ,
// "name": intentionally not styling
'regexp' : 'red'
} ;
function stylizeWithColor ( str , styleType ) {
var style = inspect . styles [ styleType ] ;
if ( style ) {
return '\u001b[' + inspect . colors [ style ] [ 0 ] + 'm' + str +
'\u001b[' + inspect . colors [ style ] [ 1 ] + 'm' ;
} else {
return str ;
}
}
function stylizeNoColor ( str , styleType ) {
return str ;
}
function arrayToHash ( array ) {
var hash = { } ;
shims . forEach ( array , function ( val , idx ) {
hash [ val ] = true ;
} ) ;
return hash ;
}
function formatValue ( ctx , value , recurseTimes ) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if ( ctx . customInspect &&
value &&
isFunction ( value . inspect ) &&
// Filter out the util module, it's inspect function is special
value . inspect !== exports . inspect &&
// Also filter out any prototype objects using the circular check.
! ( value . constructor && value . constructor . prototype === value ) ) {
var ret = value . inspect ( recurseTimes ) ;
if ( ! isString ( ret ) ) {
ret = formatValue ( ctx , ret , recurseTimes ) ;
}
return ret ;
}
// Primitive types cannot have properties
var primitive = formatPrimitive ( ctx , value ) ;
if ( primitive ) {
return primitive ;
}
// Look up the keys of the object.
var keys = shims . keys ( value ) ;
var visibleKeys = arrayToHash ( keys ) ;
if ( ctx . showHidden ) {
keys = shims . getOwnPropertyNames ( value ) ;
}
// Some type of object without properties can be shortcutted.
if ( keys . length === 0 ) {
if ( isFunction ( value ) ) {
var name = value . name ? ': ' + value . name : '' ;
return ctx . stylize ( '[Function' + name + ']' , 'special' ) ;
}
if ( isRegExp ( value ) ) {
return ctx . stylize ( RegExp . prototype . toString . call ( value ) , 'regexp' ) ;
}
if ( isDate ( value ) ) {
return ctx . stylize ( Date . prototype . toString . call ( value ) , 'date' ) ;
}
if ( isError ( value ) ) {
return formatError ( value ) ;
}
}
var base = '' , array = false , braces = [ '{' , '}' ] ;
// Make Array say that they are Array
if ( isArray ( value ) ) {
array = true ;
braces = [ '[' , ']' ] ;
}
// Make functions say that they are functions
if ( isFunction ( value ) ) {
var n = value . name ? ': ' + value . name : '' ;
base = ' [Function' + n + ']' ;
}
// Make RegExps say that they are RegExps
if ( isRegExp ( value ) ) {
base = ' ' + RegExp . prototype . toString . call ( value ) ;
}
// Make dates with properties first say the date
if ( isDate ( value ) ) {
base = ' ' + Date . prototype . toUTCString . call ( value ) ;
}
// Make error with message first say the error
if ( isError ( value ) ) {
base = ' ' + formatError ( value ) ;
}
if ( keys . length === 0 && ( ! array || value . length == 0 ) ) {
return braces [ 0 ] + base + braces [ 1 ] ;
}
if ( recurseTimes < 0 ) {
if ( isRegExp ( value ) ) {
return ctx . stylize ( RegExp . prototype . toString . call ( value ) , 'regexp' ) ;
} else {
return ctx . stylize ( '[Object]' , 'special' ) ;
}
}
ctx . seen . push ( value ) ;
var output ;
if ( array ) {
output = formatArray ( ctx , value , recurseTimes , visibleKeys , keys ) ;
} else {
output = keys . map ( function ( key ) {
return formatProperty ( ctx , value , recurseTimes , visibleKeys , key , array ) ;
} ) ;
}
ctx . seen . pop ( ) ;
return reduceToSingleString ( output , base , braces ) ;
}
function formatPrimitive ( ctx , value ) {
if ( isUndefined ( value ) )
return ctx . stylize ( 'undefined' , 'undefined' ) ;
if ( isString ( value ) ) {
var simple = '\'' + JSON . stringify ( value ) . replace ( /^"|"$/g , '' )
. replace ( /'/g , "\\'" )
. replace ( /\\"/g , '"' ) + '\'' ;
return ctx . stylize ( simple , 'string' ) ;
}
if ( isNumber ( value ) )
return ctx . stylize ( '' + value , 'number' ) ;
if ( isBoolean ( value ) )
return ctx . stylize ( '' + value , 'boolean' ) ;
// For some reason typeof null is "object", so special case here.
if ( isNull ( value ) )
return ctx . stylize ( 'null' , 'null' ) ;
}
function formatError ( value ) {
return '[' + Error . prototype . toString . call ( value ) + ']' ;
}
function formatArray ( ctx , value , recurseTimes , visibleKeys , keys ) {
var output = [ ] ;
for ( var i = 0 , l = value . length ; i < l ; ++ i ) {
if ( hasOwnProperty ( value , String ( i ) ) ) {
output . push ( formatProperty ( ctx , value , recurseTimes , visibleKeys ,
String ( i ) , true ) ) ;
} else {
output . push ( '' ) ;
}
}
shims . forEach ( keys , function ( key ) {
if ( ! key . match ( /^\d+$/ ) ) {
output . push ( formatProperty ( ctx , value , recurseTimes , visibleKeys ,
key , true ) ) ;
}
} ) ;
return output ;
}
function formatProperty ( ctx , value , recurseTimes , visibleKeys , key , array ) {
var name , str , desc ;
desc = shims . getOwnPropertyDescriptor ( value , key ) || { value : value [ key ] } ;
if ( desc . get ) {
if ( desc . set ) {
str = ctx . stylize ( '[Getter/Setter]' , 'special' ) ;
} else {
str = ctx . stylize ( '[Getter]' , 'special' ) ;
}
} else {
if ( desc . set ) {
str = ctx . stylize ( '[Setter]' , 'special' ) ;
}
}
if ( ! hasOwnProperty ( visibleKeys , key ) ) {
name = '[' + key + ']' ;
}
if ( ! str ) {
if ( shims . indexOf ( ctx . seen , desc . value ) < 0 ) {
if ( isNull ( recurseTimes ) ) {
str = formatValue ( ctx , desc . value , null ) ;
} else {
str = formatValue ( ctx , desc . value , recurseTimes - 1 ) ;
}
if ( str . indexOf ( '\n' ) > - 1 ) {
if ( array ) {
str = str . split ( '\n' ) . map ( function ( line ) {
return ' ' + line ;
} ) . join ( '\n' ) . substr ( 2 ) ;
} else {
str = '\n' + str . split ( '\n' ) . map ( function ( line ) {
return ' ' + line ;
} ) . join ( '\n' ) ;
}
}
} else {
str = ctx . stylize ( '[Circular]' , 'special' ) ;
}
}
if ( isUndefined ( name ) ) {
if ( array && key . match ( /^\d+$/ ) ) {
return str ;
}
name = JSON . stringify ( '' + key ) ;
if ( name . match ( /^"([a-zA-Z_][a-zA-Z_0-9]*)"$/ ) ) {
name = name . substr ( 1 , name . length - 2 ) ;
name = ctx . stylize ( name , 'name' ) ;
} else {
name = name . replace ( /'/g , "\\'" )
. replace ( /\\"/g , '"' )
. replace ( /(^"|"$)/g , "'" ) ;
name = ctx . stylize ( name , 'string' ) ;
}
}
return name + ': ' + str ;
}
function reduceToSingleString ( output , base , braces ) {
var numLinesEst = 0 ;
var length = shims . reduce ( output , function ( prev , cur ) {
numLinesEst ++ ;
if ( cur . indexOf ( '\n' ) >= 0 ) numLinesEst ++ ;
return prev + cur . replace ( /\u001b\[\d\d?m/g , '' ) . length + 1 ;
} , 0 ) ;
if ( length > 60 ) {
return braces [ 0 ] +
( base === '' ? '' : base + '\n ' ) +
' ' +
output . join ( ',\n ' ) +
' ' +
braces [ 1 ] ;
}
return braces [ 0 ] + base + ' ' + output . join ( ', ' ) + ' ' + braces [ 1 ] ;
}
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray ( ar ) {
return shims . isArray ( ar ) ;
}
exports . isArray = isArray ;
function isBoolean ( arg ) {
return typeof arg === 'boolean' ;
}
exports . isBoolean = isBoolean ;
function isNull ( arg ) {
return arg === null ;
}
exports . isNull = isNull ;
function isNullOrUndefined ( arg ) {
return arg == null ;
}
exports . isNullOrUndefined = isNullOrUndefined ;
function isNumber ( arg ) {
return typeof arg === 'number' ;
}
exports . isNumber = isNumber ;
function isString ( arg ) {
return typeof arg === 'string' ;
}
exports . isString = isString ;
function isSymbol ( arg ) {
return typeof arg === 'symbol' ;
}
exports . isSymbol = isSymbol ;
function isUndefined ( arg ) {
return arg === void 0 ;
}
exports . isUndefined = isUndefined ;
function isRegExp ( re ) {
return isObject ( re ) && objectToString ( re ) === '[object RegExp]' ;
}
exports . isRegExp = isRegExp ;
function isObject ( arg ) {
return typeof arg === 'object' && arg ;
}
exports . isObject = isObject ;
function isDate ( d ) {
return isObject ( d ) && objectToString ( d ) === '[object Date]' ;
}
exports . isDate = isDate ;
function isError ( e ) {
return isObject ( e ) && objectToString ( e ) === '[object Error]' ;
}
exports . isError = isError ;
function isFunction ( arg ) {
return typeof arg === 'function' ;
}
exports . isFunction = isFunction ;
function isPrimitive ( arg ) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined' ;
}
exports . isPrimitive = isPrimitive ;
function isBuffer ( arg ) {
2014-01-03 15:54:38 +00:00
return arg && typeof arg === 'object'
&& typeof arg . copy === 'function'
&& typeof arg . fill === 'function'
&& typeof arg . binarySlice === 'function'
;
2013-12-16 22:19:36 +00:00
}
exports . isBuffer = isBuffer ;
function objectToString ( o ) {
return Object . prototype . toString . call ( o ) ;
}
function pad ( n ) {
return n < 10 ? '0' + n . toString ( 10 ) : n . toString ( 10 ) ;
}
var months = [ 'Jan' , 'Feb' , 'Mar' , 'Apr' , 'May' , 'Jun' , 'Jul' , 'Aug' , 'Sep' ,
'Oct' , 'Nov' , 'Dec' ] ;
// 26 Feb 16:19:34
function timestamp ( ) {
var d = new Date ( ) ;
var time = [ pad ( d . getHours ( ) ) ,
pad ( d . getMinutes ( ) ) ,
pad ( d . getSeconds ( ) ) ] . join ( ':' ) ;
return [ d . getDate ( ) , months [ d . getMonth ( ) ] , time ] . join ( ' ' ) ;
}
// log is just a thin wrapper to console.log that prepends a timestamp
exports . log = function ( ) {
console . log ( '%s - %s' , timestamp ( ) , exports . format . apply ( exports , arguments ) ) ;
} ;
/ * *
* Inherit the prototype methods from one constructor into another .
*
* The Function . prototype . inherits from lang . js rewritten as a standalone
* function ( not on Function . prototype ) . NOTE : If this file is to be loaded
* during bootstrapping this function needs to be rewritten using some native
* functions as prototype setup using normal JavaScript does not work as
* expected during bootstrapping ( see mirror . js in r114903 ) .
*
* @ param { function } ctor Constructor function which needs to inherit the
* prototype .
* @ param { function } superCtor Constructor function to inherit prototype from .
* /
exports . inherits = function ( ctor , superCtor ) {
ctor . super _ = superCtor ;
ctor . prototype = shims . create ( superCtor . prototype , {
constructor : {
value : ctor ,
enumerable : false ,
writable : true ,
configurable : true
}
} ) ;
} ;
exports . _extend = function ( origin , add ) {
// Don't do anything if add isn't an object
if ( ! add || ! isObject ( add ) ) return origin ;
var keys = shims . keys ( add ) ;
var i = keys . length ;
while ( i -- ) {
origin [ keys [ i ] ] = add [ keys [ i ] ] ;
}
return origin ;
} ;
function hasOwnProperty ( obj , prop ) {
return Object . prototype . hasOwnProperty . call ( obj , prop ) ;
}
2014-01-03 15:54:38 +00:00
} , { "_shims" : 1 } ] , 4 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
// shim for using process in browser
var process = module . exports = { } ;
process . nextTick = ( function ( ) {
var canSetImmediate = typeof window !== 'undefined'
&& window . setImmediate ;
var canPost = typeof window !== 'undefined'
&& window . postMessage && window . addEventListener
;
if ( canSetImmediate ) {
return function ( f ) { return window . setImmediate ( f ) } ;
}
if ( canPost ) {
var queue = [ ] ;
window . addEventListener ( 'message' , function ( ev ) {
if ( ev . source === window && ev . data === 'process-tick' ) {
ev . stopPropagation ( ) ;
if ( queue . length > 0 ) {
var fn = queue . shift ( ) ;
fn ( ) ;
}
}
} , true ) ;
return function nextTick ( fn ) {
queue . push ( fn ) ;
window . postMessage ( 'process-tick' , '*' ) ;
} ;
}
return function nextTick ( fn ) {
setTimeout ( fn , 0 ) ;
} ;
} ) ( ) ;
process . title = 'browser' ;
process . browser = true ;
process . env = { } ;
process . argv = [ ] ;
process . binding = function ( name ) {
throw new Error ( 'process.binding is not supported' ) ;
}
// TODO(shtylman)
process . cwd = function ( ) { return '/' } ;
process . chdir = function ( dir ) {
throw new Error ( 'process.chdir is not supported' ) ;
} ;
2014-01-03 15:54:38 +00:00
} , { } ] , 5 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ *
Copyright ( C ) 2013 Ariya Hidayat < ariya . hidayat @ gmail . com >
Copyright ( C ) 2013 Thaddee Tyl < thaddee . tyl @ gmail . com >
Copyright ( C ) 2012 Ariya Hidayat < ariya . hidayat @ gmail . com >
Copyright ( C ) 2012 Mathias Bynens < mathias @ qiwi . be >
Copyright ( C ) 2012 Joost - Wim Boekesteijn < joost - wim @ boekesteijn . nl >
Copyright ( C ) 2012 Kris Kowal < kris . kowal @ cixar . com >
Copyright ( C ) 2012 Yusuke Suzuki < utatane . tea @ gmail . com >
Copyright ( C ) 2012 Arpad Borsos < arpad . borsos @ googlemail . com >
Copyright ( C ) 2011 Ariya Hidayat < ariya . hidayat @ gmail . com >
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL < COPYRIGHT HOLDER > BE LIABLE FOR ANY
DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
/*jslint bitwise:true plusplus:true */
/ * g l o b a l e s p r i m a : t r u e , d e f i n e : t r u e , e x p o r t s : t r u e , w i n d o w : t r u e ,
throwError : true , generateStatement : true , peek : true ,
parseAssignmentExpression : true , parseBlock : true ,
parseClassExpression : true , parseClassDeclaration : true , parseExpression : true ,
parseForStatement : true ,
parseFunctionDeclaration : true , parseFunctionExpression : true ,
parseFunctionSourceElements : true , parseVariableIdentifier : true ,
parseImportSpecifier : true ,
parseLeftHandSideExpression : true , parseParams : true , validateParam : true ,
parseSpreadOrAssignmentExpression : true ,
parseStatement : true , parseSourceElement : true , parseModuleBlock : true , parseConciseBody : true ,
advanceXJSChild : true , isXJSIdentifierStart : true , isXJSIdentifierPart : true ,
scanXJSStringLiteral : true , scanXJSIdentifier : true ,
parseXJSAttributeValue : true , parseXJSChild : true , parseXJSElement : true , parseXJSExpressionContainer : true , parseXJSEmptyExpression : true ,
2014-01-03 15:54:38 +00:00
parseTypeAnnotation : true , parseTypeAnnotatableIdentifier : true ,
2013-12-16 22:19:36 +00:00
parseYieldExpression : true
* /
( function ( root , factory ) {
'use strict' ;
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
// Rhino, and plain browser loading.
if ( typeof define === 'function' && define . amd ) {
define ( [ 'exports' ] , factory ) ;
} else if ( typeof exports !== 'undefined' ) {
factory ( exports ) ;
} else {
factory ( ( root . esprima = { } ) ) ;
}
} ( this , function ( exports ) {
'use strict' ;
var Token ,
TokenName ,
FnExprTokens ,
Syntax ,
PropertyKind ,
Messages ,
Regex ,
SyntaxTreeDelegate ,
XHTMLEntities ,
ClassPropertyType ,
source ,
strict ,
index ,
lineNumber ,
lineStart ,
length ,
delegate ,
lookahead ,
state ,
extra ;
Token = {
BooleanLiteral : 1 ,
EOF : 2 ,
Identifier : 3 ,
Keyword : 4 ,
NullLiteral : 5 ,
NumericLiteral : 6 ,
Punctuator : 7 ,
StringLiteral : 8 ,
RegularExpression : 9 ,
Template : 10 ,
XJSIdentifier : 11 ,
XJSText : 12
} ;
TokenName = { } ;
TokenName [ Token . BooleanLiteral ] = 'Boolean' ;
TokenName [ Token . EOF ] = '<end>' ;
TokenName [ Token . Identifier ] = 'Identifier' ;
TokenName [ Token . Keyword ] = 'Keyword' ;
TokenName [ Token . NullLiteral ] = 'Null' ;
TokenName [ Token . NumericLiteral ] = 'Numeric' ;
TokenName [ Token . Punctuator ] = 'Punctuator' ;
TokenName [ Token . StringLiteral ] = 'String' ;
TokenName [ Token . XJSIdentifier ] = 'XJSIdentifier' ;
TokenName [ Token . XJSText ] = 'XJSText' ;
TokenName [ Token . RegularExpression ] = 'RegularExpression' ;
// A function following one of those tokens is an expression.
FnExprTokens = [ "(" , "{" , "[" , "in" , "typeof" , "instanceof" , "new" ,
"return" , "case" , "delete" , "throw" , "void" ,
// assignment operators
"=" , "+=" , "-=" , "*=" , "/=" , "%=" , "<<=" , ">>=" , ">>>=" ,
"&=" , "|=" , "^=" , "," ,
// binary/unary operators
"+" , "-" , "*" , "/" , "%" , "++" , "--" , "<<" , ">>" , ">>>" , "&" ,
"|" , "^" , "!" , "~" , "&&" , "||" , "?" , ":" , "===" , "==" , ">=" ,
"<=" , "<" , ">" , "!=" , "!==" ] ;
Syntax = {
ArrayExpression : 'ArrayExpression' ,
ArrayPattern : 'ArrayPattern' ,
ArrowFunctionExpression : 'ArrowFunctionExpression' ,
AssignmentExpression : 'AssignmentExpression' ,
BinaryExpression : 'BinaryExpression' ,
BlockStatement : 'BlockStatement' ,
BreakStatement : 'BreakStatement' ,
CallExpression : 'CallExpression' ,
CatchClause : 'CatchClause' ,
ClassBody : 'ClassBody' ,
ClassDeclaration : 'ClassDeclaration' ,
ClassExpression : 'ClassExpression' ,
ClassHeritage : 'ClassHeritage' ,
ComprehensionBlock : 'ComprehensionBlock' ,
ComprehensionExpression : 'ComprehensionExpression' ,
ConditionalExpression : 'ConditionalExpression' ,
ContinueStatement : 'ContinueStatement' ,
DebuggerStatement : 'DebuggerStatement' ,
DoWhileStatement : 'DoWhileStatement' ,
EmptyStatement : 'EmptyStatement' ,
ExportDeclaration : 'ExportDeclaration' ,
ExportBatchSpecifier : 'ExportBatchSpecifier' ,
ExportSpecifier : 'ExportSpecifier' ,
ExpressionStatement : 'ExpressionStatement' ,
ForInStatement : 'ForInStatement' ,
ForOfStatement : 'ForOfStatement' ,
ForStatement : 'ForStatement' ,
FunctionDeclaration : 'FunctionDeclaration' ,
FunctionExpression : 'FunctionExpression' ,
Identifier : 'Identifier' ,
IfStatement : 'IfStatement' ,
ImportDeclaration : 'ImportDeclaration' ,
ImportSpecifier : 'ImportSpecifier' ,
LabeledStatement : 'LabeledStatement' ,
Literal : 'Literal' ,
LogicalExpression : 'LogicalExpression' ,
MemberExpression : 'MemberExpression' ,
MethodDefinition : 'MethodDefinition' ,
ModuleDeclaration : 'ModuleDeclaration' ,
NewExpression : 'NewExpression' ,
ObjectExpression : 'ObjectExpression' ,
ObjectPattern : 'ObjectPattern' ,
Program : 'Program' ,
Property : 'Property' ,
ReturnStatement : 'ReturnStatement' ,
SequenceExpression : 'SequenceExpression' ,
SpreadElement : 'SpreadElement' ,
SwitchCase : 'SwitchCase' ,
SwitchStatement : 'SwitchStatement' ,
TaggedTemplateExpression : 'TaggedTemplateExpression' ,
TemplateElement : 'TemplateElement' ,
TemplateLiteral : 'TemplateLiteral' ,
ThisExpression : 'ThisExpression' ,
ThrowStatement : 'ThrowStatement' ,
TryStatement : 'TryStatement' ,
TypeAnnotatedIdentifier : 'TypeAnnotatedIdentifier' ,
TypeAnnotation : 'TypeAnnotation' ,
UnaryExpression : 'UnaryExpression' ,
UpdateExpression : 'UpdateExpression' ,
VariableDeclaration : 'VariableDeclaration' ,
VariableDeclarator : 'VariableDeclarator' ,
WhileStatement : 'WhileStatement' ,
WithStatement : 'WithStatement' ,
XJSIdentifier : 'XJSIdentifier' ,
XJSEmptyExpression : 'XJSEmptyExpression' ,
XJSExpressionContainer : 'XJSExpressionContainer' ,
XJSElement : 'XJSElement' ,
XJSClosingElement : 'XJSClosingElement' ,
XJSOpeningElement : 'XJSOpeningElement' ,
XJSAttribute : 'XJSAttribute' ,
XJSText : 'XJSText' ,
YieldExpression : 'YieldExpression'
} ;
PropertyKind = {
Data : 1 ,
Get : 2 ,
Set : 4
} ;
ClassPropertyType = {
static : 'static' ,
prototype : 'prototype'
} ;
// Error messages should be identical to V8.
Messages = {
UnexpectedToken : 'Unexpected token %0' ,
UnexpectedNumber : 'Unexpected number' ,
UnexpectedString : 'Unexpected string' ,
UnexpectedIdentifier : 'Unexpected identifier' ,
UnexpectedReserved : 'Unexpected reserved word' ,
UnexpectedTemplate : 'Unexpected quasi %0' ,
UnexpectedEOS : 'Unexpected end of input' ,
NewlineAfterThrow : 'Illegal newline after throw' ,
InvalidRegExp : 'Invalid regular expression' ,
UnterminatedRegExp : 'Invalid regular expression: missing /' ,
InvalidLHSInAssignment : 'Invalid left-hand side in assignment' ,
InvalidLHSInFormalsList : 'Invalid left-hand side in formals list' ,
InvalidLHSInForIn : 'Invalid left-hand side in for-in' ,
MultipleDefaultsInSwitch : 'More than one default clause in switch statement' ,
NoCatchOrFinally : 'Missing catch or finally after try' ,
UnknownLabel : 'Undefined label \'%0\'' ,
Redeclaration : '%0 \'%1\' has already been declared' ,
IllegalContinue : 'Illegal continue statement' ,
IllegalBreak : 'Illegal break statement' ,
IllegalDuplicateClassProperty : 'Illegal duplicate property in class definition' ,
IllegalReturn : 'Illegal return statement' ,
IllegalYield : 'Illegal yield expression' ,
IllegalSpread : 'Illegal spread element' ,
StrictModeWith : 'Strict mode code may not include a with statement' ,
StrictCatchVariable : 'Catch variable may not be eval or arguments in strict mode' ,
StrictVarName : 'Variable name may not be eval or arguments in strict mode' ,
StrictParamName : 'Parameter name eval or arguments is not allowed in strict mode' ,
StrictParamDupe : 'Strict mode function may not have duplicate parameter names' ,
ParameterAfterRestParameter : 'Rest parameter must be final parameter of an argument list' ,
DefaultRestParameter : 'Rest parameter can not have a default value' ,
ElementAfterSpreadElement : 'Spread must be the final element of an element list' ,
ObjectPatternAsRestParameter : 'Invalid rest parameter' ,
ObjectPatternAsSpread : 'Invalid spread argument' ,
StrictFunctionName : 'Function name may not be eval or arguments in strict mode' ,
StrictOctalLiteral : 'Octal literals are not allowed in strict mode.' ,
StrictDelete : 'Delete of an unqualified identifier in strict mode.' ,
StrictDuplicateProperty : 'Duplicate data property in object literal not allowed in strict mode' ,
AccessorDataProperty : 'Object literal may not have data and accessor property with the same name' ,
AccessorGetSet : 'Object literal may not have multiple get/set accessors with the same name' ,
StrictLHSAssignment : 'Assignment to eval or arguments is not allowed in strict mode' ,
StrictLHSPostfix : 'Postfix increment/decrement may not have eval or arguments operand in strict mode' ,
StrictLHSPrefix : 'Prefix increment/decrement may not have eval or arguments operand in strict mode' ,
StrictReservedWord : 'Use of future reserved word in strict mode' ,
NewlineAfterModule : 'Illegal newline after module' ,
NoFromAfterImport : 'Missing from after import' ,
InvalidModuleSpecifier : 'Invalid module specifier' ,
NestedModule : 'Module declaration can not be nested' ,
NoYieldInGenerator : 'Missing yield in generator' ,
NoUnintializedConst : 'Const must be initialized' ,
ComprehensionRequiresBlock : 'Comprehension must have at least one block' ,
ComprehensionError : 'Comprehension Error' ,
EachNotAllowed : 'Each is not supported' ,
InvalidXJSTagName : 'XJS tag name can not be empty' ,
InvalidXJSAttributeValue : 'XJS value should be either an expression or a quoted XJS text' ,
ExpectedXJSClosingTag : 'Expected corresponding XJS closing tag for %0'
} ;
// See also tools/generate-unicode-regex.py.
Regex = {
NonAsciiIdentifierStart : new RegExp ( ' [ \ xaa \ xb5 \ xba \ xc0 - \ xd6 \ xd8 - \ xf6 \ xf8 - \u02c1\u02c6 - \u02d1\u02e0 - \u02e4\u02ec\u02ee\u0370 - \u0374\u0376\u0377\u037a - \u037d\u0386\u0388 - \u038a\u038c\u038e - \u03a1\u03a3 - \u03f5\u03f7 - \u0481\u048a - \u0527\u0531 - \u0556\u0559\u0561 - \u0587\u05d0 - \u05ea\u05f0 - \u05f2\u0620 - \u064a\u066e\u066f\u0671 - \u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa - \u06fc\u06ff\u0710\u0712 - \u072f\u074d - \u07a5\u07b1\u07ca - \u07ea\u07f4\u07f5\u07fa\u0800 - \u0815\u081a\u0824\u0828\u0840 - \u0858\u08a0\u08a2 - \u08ac\u0904 - \u0939\u093d\u0950\u0958 - \u0961\u0971 - \u0977\u0979 - \u097f\u0985 - \u098c\u098f\u0990\u0993 - \u09a8\u09aa - \u09b0\u09b2\u09b6 - \u09b9\u09bd\u09ce\u09dc\u09dd\u09df - \u09e1\u09f0\u09f1\u0a05 - \u0a0a\u0a0f\u0a10\u0a13 - \u0a28\u0a2a - \u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59 - \u0a5c\u0a5e\u0a72 - \u0a74\u0a85 - \u0a8d\u0a8f - \u0a91\u0a93 - \u0aa8\u0aaa - \u0ab0\u0ab2\u0ab3\u0ab5 - \u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05 - \u0b0c\u0b0f\u0b10\u0b13 - \u0b28\u0b2a - \u0b30\u0b32\u0b33\u0b35 - \u0b39\u0b3d\u0b5c\u0b5d\u0b5f - \u0b61\u0b71\u0b83\u0b85 - \u0b8a\u0b8e - \u0b90\u0b92 - \u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8 - \u0baa\u0bae - \u0bb9\u0bd0\u0c05 - \u0c0c\u0c0e - \u0c10\u0c12 - \u0c28\u0c2a - \u0c33\u0c35 - \u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85 - \u0c8c\u0c8e - \u0c90\u0c92 - \u0ca8\u0caa - \u0cb3\u0cb5 - \u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05 - \u0d0c\u0d0e - \u0d10\u0d12 - \u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a - \u0d7f\u0d85 - \u0d96\u0d9a - \u0db1\u0db3 - \u0dbb\u0dbd\u0dc0 - \u0dc6\u0e01 - \u0e30\u0e32\u0e33\u0e40 - \u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94 - \u0e97\u0e99 - \u0e9f\u0ea1 - \u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead - \u0eb0\u0eb2\u0eb3\u0ebd\u0ec0 - \u0ec4\u0ec6\u0edc - \u0edf\u0f00\u0f40 - \u0f47\u0f49 - \u0f6c\u0f88 - \u0f8c\u1000 - \u102a\u103f\u1050 - \u1055\u105a - \u105d\u1061\u1065\u1066\u106e - \u1070\u1075 - \u1081\u108e\u10a0 - \u10c5\u10c7\u10cd\u10d0 - \u10fa\u10fc - \u1248\u124a - \u124d\u1250 - \u1256\u1258\u125a - \u125d\u1260 - \u1288\u128a - \u128d\u1290 - \u12b0\u12b2 - \u12b5\u12b8 - \u12be\u12c0\u12c2 - \u12c5\u12c8 - \u12d6\u12d8 - \u1310\u1312 - \u1315\u1318 - \u135a\u1380 - \u138f\u13a0 - \u13f4\u1401 - \u166c\u166f - \u167f\u1681 - \u169a\u16a0 - \u16ea\u16ee - \u16f0\u1700 - \u170c\u170e - \u1711\u1720 - \u1731\u1740 - \u1751\u1760 - \u176c\u176e - \u1770\u1780 - \u17b3\u17d7\u17dc\u1820 - \u1877\u1880 - \u18a8\u18aa\u18b0 - \u18f5\u1900 - \u191c\u1950 - \u196d\u1970 - \u1974\u1980 - \u19ab\u19c1 - \u19c7\u1a00 - \u1a16\u1a20 - \u1a54\u1aa7\u1b05 - \u1b33\u1b45 - \u1b4b\u1b83 - \u1ba0\u1bae\u1baf\u1bba - \u1be5\u1c00 - \u1c23\u1c4d - \u1c4f\u1c5a - \u1c7d\u1ce9 - \u1cec\u1cee - \u1cf1\u1cf5\u1cf6\u1d00 - \u1dbf\u1e00 - \u1f15\u1f18 - \u1f1d\u1f20 - \u1f45\u1f48 - \u1f4d\u1f50 - \u1f57\u1f59\u1f5b\u1f5d\u1f5f - \u1f7d\u1f80 - \u1fb4\u1fb6 - \u1fbc\u1fbe\u1fc2 - \u1fc4\u1fc6 - \u1fcc\u1fd0 - \u1fd3\u1fd6 - \u1fdb\u1fe0 - \u1fec\u1ff2 - \u1ff4\u1ff6 - \u1ffc\u2071\u207f\u2090 - \u209c\u2102\u2107\u210a - \u2113\u2115\u2119 - \u211d\u2124\u2126\u2128\u212a - \u212d\u212f - \u2139\u213c - \u213f\u2145 - \u2149\u214e\u2160 - \u2188\u2c00 - \u2c2e\u2c30 - \u2c5e\u2c60 - \u2ce4\u2ceb - \u2cee\u2cf2\u2cf3\u2d00 - \u2d25\u2d27\u2d2d\u2d30 - \u2d67\u2d6f\u2d80 - \u2d96\u2da0 - \u2da6\u2da8 - \u2dae\u2db0 - \u2db6\u2db8 - \u2dbe\u2dc0 - \u2dc6\u2dc8 - \u2dce\u2dd0 - \u2dd6\u2dd8 - \u2dde\u2e2f\u3005 - \u3007\u3021 - \u3029\u3031 - \u3035\u3038 - \u303c\u3041 - \u3096\u309d - \u309f\u30a1 - \u30fa\u30fc - \u30ff\u3105 - \u312d\u3131 - \u318e\u31a0 - \u31ba\u31f0 - \u31ff\u3400 - \u4db5\u4e00 - \u9fcc\ua000 - \ua48c\ua4d0 - \ua4fd\ua500 - \ua60c\ua610 - \ua61f\ua62a\ua62b\ua640 - \ua66e\ua67f - \ua697\ua6a0 - \ua6ef\ua717 - \ua71f\ua722 - \ua788\ua78b - \ua78e\ua790 - \ua793\ua7a0 - \ua7aa\ua7f8 - \ua801\ua803 - \ua805\ua807 - \ua80a\ua80c - \ua822\ua840 - \ua873\ua882 - \ua8b3\ua8f2 - \ua8f7\ua8fb\ua90a - \ua925\ua930 - \ua946\ua960 - \ua97c\ua984 - \ua9b2\ua9cf\uaa00 - \uaa28\uaa40 - \uaa42\uaa44 - \uaa4b\uaa60 - \uaa76\uaa7a\uaa80 - \uaaaf\uaab1\uaab5\uaab6\uaab9 - \uaabd\uaac0\uaac2\uaadb - \uaadd\uaae0 - \uaaea\uaaf2 - \uaaf4\uab01 - \uab06\uab09 - \uab0e\uab11 - \uab16\uab20 - \uab26\uab28 - \uab2e\uabc0 - \uabe2\uac00 - \ud7a3\ud7b0 - \ud7c6\ud7cb - \ud7fb\uf900 - \ufa6d\ufa70 - \ufad9\ufb00 - \ufb06\ufb13 - \ufb17\ufb1d\ufb1f - \ufb28\ufb2a - \ufb36\ufb38 - \ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46 - \ufbb1\ufbd3 - \ufd3d\ufd50 - \ u
NonAsciiIdentifierPart : new RegExp ( ' [ \ xaa \ xb5 \ xba \ xc0 - \ xd6 \ xd8 - \ xf6 \ xf8 - \u02c1\u02c6 - \u02d1\u02e0 - \u02e4\u02ec\u02ee\u0300 - \u0374\u0376\u0377\u037a - \u037d\u0386\u0388 - \u038a\u038c\u038e - \u03a1\u03a3 - \u03f5\u03f7 - \u0481\u0483 - \u0487\u048a - \u0527\u0531 - \u0556\u0559\u0561 - \u0587\u0591 - \u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0 - \u05ea\u05f0 - \u05f2\u0610 - \u061a\u0620 - \u0669\u066e - \u06d3\u06d5 - \u06dc\u06df - \u06e8\u06ea - \u06fc\u06ff\u0710 - \u074a\u074d - \u07b1\u07c0 - \u07f5\u07fa\u0800 - \u082d\u0840 - \u085b\u08a0\u08a2 - \u08ac\u08e4 - \u08fe\u0900 - \u0963\u0966 - \u096f\u0971 - \u0977\u0979 - \u097f\u0981 - \u0983\u0985 - \u098c\u098f\u0990\u0993 - \u09a8\u09aa - \u09b0\u09b2\u09b6 - \u09b9\u09bc - \u09c4\u09c7\u09c8\u09cb - \u09ce\u09d7\u09dc\u09dd\u09df - \u09e3\u09e6 - \u09f1\u0a01 - \u0a03\u0a05 - \u0a0a\u0a0f\u0a10\u0a13 - \u0a28\u0a2a - \u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e - \u0a42\u0a47\u0a48\u0a4b - \u0a4d\u0a51\u0a59 - \u0a5c\u0a5e\u0a66 - \u0a75\u0a81 - \u0a83\u0a85 - \u0a8d\u0a8f - \u0a91\u0a93 - \u0aa8\u0aaa - \u0ab0\u0ab2\u0ab3\u0ab5 - \u0ab9\u0abc - \u0ac5\u0ac7 - \u0ac9\u0acb - \u0acd\u0ad0\u0ae0 - \u0ae3\u0ae6 - \u0aef\u0b01 - \u0b03\u0b05 - \u0b0c\u0b0f\u0b10\u0b13 - \u0b28\u0b2a - \u0b30\u0b32\u0b33\u0b35 - \u0b39\u0b3c - \u0b44\u0b47\u0b48\u0b4b - \u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f - \u0b63\u0b66 - \u0b6f\u0b71\u0b82\u0b83\u0b85 - \u0b8a\u0b8e - \u0b90\u0b92 - \u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8 - \u0baa\u0bae - \u0bb9\u0bbe - \u0bc2\u0bc6 - \u0bc8\u0bca - \u0bcd\u0bd0\u0bd7\u0be6 - \u0bef\u0c01 - \u0c03\u0c05 - \u0c0c\u0c0e - \u0c10\u0c12 - \u0c28\u0c2a - \u0c33\u0c35 - \u0c39\u0c3d - \u0c44\u0c46 - \u0c48\u0c4a - \u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60 - \u0c63\u0c66 - \u0c6f\u0c82\u0c83\u0c85 - \u0c8c\u0c8e - \u0c90\u0c92 - \u0ca8\u0caa - \u0cb3\u0cb5 - \u0cb9\u0cbc - \u0cc4\u0cc6 - \u0cc8\u0cca - \u0ccd\u0cd5\u0cd6\u0cde\u0ce0 - \u0ce3\u0ce6 - \u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05 - \u0d0c\u0d0e - \u0d10\u0d12 - \u0d3a\u0d3d - \u0d44\u0d46 - \u0d48\u0d4a - \u0d4e\u0d57\u0d60 - \u0d63\u0d66 - \u0d6f\u0d7a - \u0d7f\u0d82\u0d83\u0d85 - \u0d96\u0d9a - \u0db1\u0db3 - \u0dbb\u0dbd\u0dc0 - \u0dc6\u0dca\u0dcf - \u0dd4\u0dd6\u0dd8 - \u0ddf\u0df2\u0df3\u0e01 - \u0e3a\u0e40 - \u0e4e\u0e50 - \u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94 - \u0e97\u0e99 - \u0e9f\u0ea1 - \u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead - \u0eb9\u0ebb - \u0ebd\u0ec0 - \u0ec4\u0ec6\u0ec8 - \u0ecd\u0ed0 - \u0ed9\u0edc - \u0edf\u0f00\u0f18\u0f19\u0f20 - \u0f29\u0f35\u0f37\u0f39\u0f3e - \u0f47\u0f49 - \u0f6c\u0f71 - \u0f84\u0f86 - \u0f97\u0f99 - \u0fbc\u0fc6\u1000 - \u1049\u1050 - \u109d\u10a0 - \u10c5\u10c7\u10cd\u10d0 - \u10fa\u10fc - \u1248\u124a - \u124d\u1250 - \u1256\u1258\u125a - \u125d\u1260 - \u1288\u128a - \u128d\u1290 - \u12b0\u12b2 - \u12b5\u12b8 - \u12be\u12c0\u12c2 - \u12c5\u12c8 - \u12d6\u12d8 - \u1310\u1312 - \u1315\u1318 - \u135a\u135d - \u135f\u1380 - \u138f\u13a0 - \u13f4\u1401 - \u166c\u166f - \u167f\u1681 - \u169a\u16a0 - \u16ea\u16ee - \u16f0\u1700 - \u170c\u170e - \u1714\u1720 - \u1734\u1740 - \u1753\u1760 - \u176c\u176e - \u1770\u1772\u1773\u1780 - \u17d3\u17d7\u17dc\u17dd\u17e0 - \u17e9\u180b - \u180d\u1810 - \u1819\u1820 - \u1877\u1880 - \u18aa\u18b0 - \u18f5\u1900 - \u191c\u1920 - \u192b\u1930 - \u193b\u1946 - \u196d\u1970 - \u1974\u1980 - \u19ab\u19b0 - \u19c9\u19d0 - \u19d9\u1a00 - \u1a1b\u1a20 - \u1a5e\u1a60 - \u1a7c\u1a7f - \u1a89\u1a90 - \u1a99\u1aa7\u1b00 - \u1b4b\u1b50 - \u1b59\u1b6b - \u1b73\u1b80 - \u1bf3\u1c00 - \u1c37\u1c40 - \u1c49\u1c4d - \u1c7d\u1cd0 - \u1cd2\u1cd4 - \u1cf6\u1d00 - \u1de6\u1dfc - \u1f15\u1f18 - \u1f1d\u1f20 - \u1f45\u1f48 - \u1f4d\u1f50 - \u1f57\u1f59\u1f5b\u1f5d\u1f5f - \u1f7d\u1f80 - \u1fb4\u1fb6 - \u1fbc\u1fbe\u1fc2 - \u1fc4\u1fc6 - \u1fcc\u1fd0 - \u1fd3\u1fd6 - \u1fdb\u1fe0 - \u1fec\u1ff2 - \u1ff4\u1ff6 - \u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090 - \u209c\u20d0 - \u20dc\u20e1\u20e5 - \u20f0\u2102\u2107\u210a - \u2113\u2115\u2119 - \u211d\u2124\u2126\u2128\u212a - \u212d\u212f - \u2139\u213c - \u213f\u2145 - \u2149\u214e\u2160 - \u2188\u2c00 - \u2c2e\u2c30 - \u2c5e\u2c60 - \u2ce4\u2ceb - \u2cf3\u2d00 - \u2d25\u2d27\u2d2d\u2d30 - \u2d67\u2d6f\u2d7f - \u2d96\u2da0 - \u2da6\u2da8 - \u2dae\u2db0 - \u2db6\u2db8 - \u2dbe\u2dc0 - \u2dc6\u2dc8 - \u2dce\u2dd0 - \u2dd6\u2dd8 - \u2dde\u2de0 - \u2dff\u2e2f\u3005 - \u3007\u3021 - \u302f\u3031 - \u3035\u3038 - \u303c\u3041 - \u3096\u3099\u309a\u309d - \u309f\u30a1 - \u30fa\u30fc - \u30ff\u3105 - \u312d\u3131 - \u318e \ u
} ;
// Ensure the condition is true, otherwise throw an error.
// This is only to have a better contract semantic, i.e. another safety net
// to catch a logic error. The condition shall be fulfilled in normal case.
// Do NOT use this to enforce a certain condition on any user input.
function assert ( condition , message ) {
if ( ! condition ) {
throw new Error ( 'ASSERT: ' + message ) ;
}
}
function isDecimalDigit ( ch ) {
return ( ch >= 48 && ch <= 57 ) ; // 0..9
}
function isHexDigit ( ch ) {
return '0123456789abcdefABCDEF' . indexOf ( ch ) >= 0 ;
}
function isOctalDigit ( ch ) {
return '01234567' . indexOf ( ch ) >= 0 ;
}
// 7.2 White Space
function isWhiteSpace ( ch ) {
return ( ch === 32 ) || // space
( ch === 9 ) || // tab
( ch === 0xB ) ||
( ch === 0xC ) ||
( ch === 0xA0 ) ||
( ch >= 0x1680 && '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF' . indexOf ( String . fromCharCode ( ch ) ) > 0 ) ;
}
// 7.3 Line Terminators
function isLineTerminator ( ch ) {
return ( ch === 10 ) || ( ch === 13 ) || ( ch === 0x2028 ) || ( ch === 0x2029 ) ;
}
// 7.6 Identifier Names and Identifiers
function isIdentifierStart ( ch ) {
return ( ch === 36 ) || ( ch === 95 ) || // $ (dollar) and _ (underscore)
( ch >= 65 && ch <= 90 ) || // A..Z
( ch >= 97 && ch <= 122 ) || // a..z
( ch === 92 ) || // \ (backslash)
( ( ch >= 0x80 ) && Regex . NonAsciiIdentifierStart . test ( String . fromCharCode ( ch ) ) ) ;
}
function isIdentifierPart ( ch ) {
return ( ch === 36 ) || ( ch === 95 ) || // $ (dollar) and _ (underscore)
( ch >= 65 && ch <= 90 ) || // A..Z
( ch >= 97 && ch <= 122 ) || // a..z
( ch >= 48 && ch <= 57 ) || // 0..9
( ch === 92 ) || // \ (backslash)
( ( ch >= 0x80 ) && Regex . NonAsciiIdentifierPart . test ( String . fromCharCode ( ch ) ) ) ;
}
// 7.6.1.2 Future Reserved Words
function isFutureReservedWord ( id ) {
switch ( id ) {
case 'class' :
case 'enum' :
case 'export' :
case 'extends' :
case 'import' :
case 'super' :
return true ;
default :
return false ;
}
}
function isStrictModeReservedWord ( id ) {
switch ( id ) {
case 'implements' :
case 'interface' :
case 'package' :
case 'private' :
case 'protected' :
case 'public' :
case 'static' :
case 'yield' :
case 'let' :
return true ;
default :
return false ;
}
}
function isRestrictedWord ( id ) {
return id === 'eval' || id === 'arguments' ;
}
// 7.6.1.1 Keywords
function isKeyword ( id ) {
if ( strict && isStrictModeReservedWord ( id ) ) {
return true ;
}
// 'const' is specialized as Keyword in V8.
// 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.
// Some others are from future reserved words.
switch ( id . length ) {
case 2 :
return ( id === 'if' ) || ( id === 'in' ) || ( id === 'do' ) ;
case 3 :
return ( id === 'var' ) || ( id === 'for' ) || ( id === 'new' ) ||
( id === 'try' ) || ( id === 'let' ) ;
case 4 :
return ( id === 'this' ) || ( id === 'else' ) || ( id === 'case' ) ||
( id === 'void' ) || ( id === 'with' ) || ( id === 'enum' ) ;
case 5 :
return ( id === 'while' ) || ( id === 'break' ) || ( id === 'catch' ) ||
( id === 'throw' ) || ( id === 'const' ) || ( id === 'yield' ) ||
( id === 'class' ) || ( id === 'super' ) ;
case 6 :
return ( id === 'return' ) || ( id === 'typeof' ) || ( id === 'delete' ) ||
( id === 'switch' ) || ( id === 'export' ) || ( id === 'import' ) ;
case 7 :
return ( id === 'default' ) || ( id === 'finally' ) || ( id === 'extends' ) ;
case 8 :
return ( id === 'function' ) || ( id === 'continue' ) || ( id === 'debugger' ) ;
case 10 :
return ( id === 'instanceof' ) ;
default :
return false ;
}
}
// 7.4 Comments
function skipComment ( ) {
var ch , blockComment , lineComment ;
blockComment = false ;
lineComment = false ;
while ( index < length ) {
ch = source . charCodeAt ( index ) ;
if ( lineComment ) {
++ index ;
if ( isLineTerminator ( ch ) ) {
lineComment = false ;
if ( ch === 13 && source . charCodeAt ( index ) === 10 ) {
++ index ;
}
++ lineNumber ;
lineStart = index ;
}
} else if ( blockComment ) {
if ( isLineTerminator ( ch ) ) {
if ( ch === 13 && source . charCodeAt ( index + 1 ) === 10 ) {
++ index ;
}
++ lineNumber ;
++ index ;
lineStart = index ;
if ( index >= length ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
} else {
ch = source . charCodeAt ( index ++ ) ;
if ( index >= length ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
// Block comment ends with '*/' (char #42, char #47).
if ( ch === 42 ) {
ch = source . charCodeAt ( index ) ;
if ( ch === 47 ) {
++ index ;
blockComment = false ;
}
}
}
} else if ( ch === 47 ) {
ch = source . charCodeAt ( index + 1 ) ;
// Line comment starts with '//' (char #47, char #47).
if ( ch === 47 ) {
index += 2 ;
lineComment = true ;
} else if ( ch === 42 ) {
// Block comment starts with '/*' (char #47, char #42).
index += 2 ;
blockComment = true ;
if ( index >= length ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
} else {
break ;
}
} else if ( isWhiteSpace ( ch ) ) {
++ index ;
} else if ( isLineTerminator ( ch ) ) {
++ index ;
if ( ch === 13 && source . charCodeAt ( index ) === 10 ) {
++ index ;
}
++ lineNumber ;
lineStart = index ;
} else {
break ;
}
}
}
function scanHexEscape ( prefix ) {
var i , len , ch , code = 0 ;
len = ( prefix === 'u' ) ? 4 : 2 ;
for ( i = 0 ; i < len ; ++ i ) {
if ( index < length && isHexDigit ( source [ index ] ) ) {
ch = source [ index ++ ] ;
code = code * 16 + '0123456789abcdef' . indexOf ( ch . toLowerCase ( ) ) ;
} else {
return '' ;
}
}
return String . fromCharCode ( code ) ;
}
function scanUnicodeCodePointEscape ( ) {
var ch , code , cu1 , cu2 ;
ch = source [ index ] ;
code = 0 ;
// At least, one hex digit is required.
if ( ch === '}' ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
while ( index < length ) {
ch = source [ index ++ ] ;
if ( ! isHexDigit ( ch ) ) {
break ;
}
code = code * 16 + '0123456789abcdef' . indexOf ( ch . toLowerCase ( ) ) ;
}
if ( code > 0x10FFFF || ch !== '}' ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
// UTF-16 Encoding
if ( code <= 0xFFFF ) {
return String . fromCharCode ( code ) ;
}
cu1 = ( ( code - 0x10000 ) >> 10 ) + 0xD800 ;
cu2 = ( ( code - 0x10000 ) & 1023 ) + 0xDC00 ;
return String . fromCharCode ( cu1 , cu2 ) ;
}
function getEscapedIdentifier ( ) {
var ch , id ;
ch = source . charCodeAt ( index ++ ) ;
id = String . fromCharCode ( ch ) ;
// '\u' (char #92, char #117) denotes an escaped character.
if ( ch === 92 ) {
if ( source . charCodeAt ( index ) !== 117 ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
++ index ;
ch = scanHexEscape ( 'u' ) ;
if ( ! ch || ch === '\\' || ! isIdentifierStart ( ch . charCodeAt ( 0 ) ) ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
id = ch ;
}
while ( index < length ) {
ch = source . charCodeAt ( index ) ;
if ( ! isIdentifierPart ( ch ) ) {
break ;
}
++ index ;
id += String . fromCharCode ( ch ) ;
// '\u' (char #92, char #117) denotes an escaped character.
if ( ch === 92 ) {
id = id . substr ( 0 , id . length - 1 ) ;
if ( source . charCodeAt ( index ) !== 117 ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
++ index ;
ch = scanHexEscape ( 'u' ) ;
if ( ! ch || ch === '\\' || ! isIdentifierPart ( ch . charCodeAt ( 0 ) ) ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
id += ch ;
}
}
return id ;
}
function getIdentifier ( ) {
var start , ch ;
start = index ++ ;
while ( index < length ) {
ch = source . charCodeAt ( index ) ;
if ( ch === 92 ) {
// Blackslash (char #92) marks Unicode escape sequence.
index = start ;
return getEscapedIdentifier ( ) ;
}
if ( isIdentifierPart ( ch ) ) {
++ index ;
} else {
break ;
}
}
return source . slice ( start , index ) ;
}
function scanIdentifier ( ) {
var start , id , type ;
start = index ;
// Backslash (char #92) starts an escaped character.
id = ( source . charCodeAt ( index ) === 92 ) ? getEscapedIdentifier ( ) : getIdentifier ( ) ;
// There is no keyword or literal with only one character.
// Thus, it must be an identifier.
if ( id . length === 1 ) {
type = Token . Identifier ;
} else if ( isKeyword ( id ) ) {
type = Token . Keyword ;
} else if ( id === 'null' ) {
type = Token . NullLiteral ;
} else if ( id === 'true' || id === 'false' ) {
type = Token . BooleanLiteral ;
} else {
type = Token . Identifier ;
}
return {
type : type ,
value : id ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
// 7.7 Punctuators
function scanPunctuator ( ) {
var start = index ,
code = source . charCodeAt ( index ) ,
code2 ,
ch1 = source [ index ] ,
ch2 ,
ch3 ,
ch4 ;
switch ( code ) {
// Check for most common single-character punctuators.
case 40 : // ( open bracket
case 41 : // ) close bracket
case 59 : // ; semicolon
case 44 : // , comma
case 123 : // { open curly brace
case 125 : // } close curly brace
case 91 : // [
case 93 : // ]
case 58 : // :
case 63 : // ?
case 126 : // ~
++ index ;
if ( extra . tokenize ) {
if ( code === 40 ) {
extra . openParenToken = extra . tokens . length ;
} else if ( code === 123 ) {
extra . openCurlyToken = extra . tokens . length ;
}
}
return {
type : Token . Punctuator ,
value : String . fromCharCode ( code ) ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
default :
code2 = source . charCodeAt ( index + 1 ) ;
// '=' (char #61) marks an assignment or comparison operator.
if ( code2 === 61 ) {
switch ( code ) {
case 37 : // %
case 38 : // &
case 42 : // *:
case 43 : // +
case 45 : // -
case 47 : // /
case 60 : // <
case 62 : // >
case 94 : // ^
case 124 : // |
index += 2 ;
return {
type : Token . Punctuator ,
value : String . fromCharCode ( code ) + String . fromCharCode ( code2 ) ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
case 33 : // !
case 61 : // =
index += 2 ;
// !== and ===
if ( source . charCodeAt ( index ) === 61 ) {
++ index ;
}
return {
type : Token . Punctuator ,
value : source . slice ( start , index ) ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
default :
break ;
}
}
break ;
}
// Peek more characters.
ch2 = source [ index + 1 ] ;
ch3 = source [ index + 2 ] ;
ch4 = source [ index + 3 ] ;
// 4-character punctuator: >>>=
if ( ch1 === '>' && ch2 === '>' && ch3 === '>' ) {
if ( ch4 === '=' ) {
index += 4 ;
return {
type : Token . Punctuator ,
value : '>>>=' ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
}
// 3-character punctuators: === !== >>> <<= >>=
if ( ch1 === '>' && ch2 === '>' && ch3 === '>' ) {
index += 3 ;
return {
type : Token . Punctuator ,
value : '>>>' ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
if ( ch1 === '<' && ch2 === '<' && ch3 === '=' ) {
index += 3 ;
return {
type : Token . Punctuator ,
value : '<<=' ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
if ( ch1 === '>' && ch2 === '>' && ch3 === '=' ) {
index += 3 ;
return {
type : Token . Punctuator ,
value : '>>=' ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
if ( ch1 === '.' && ch2 === '.' && ch3 === '.' ) {
index += 3 ;
return {
type : Token . Punctuator ,
value : '...' ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
// Other 2-character punctuators: ++ -- << >> && ||
if ( ch1 === ch2 && ( '+-<>&|' . indexOf ( ch1 ) >= 0 ) ) {
index += 2 ;
return {
type : Token . Punctuator ,
value : ch1 + ch2 ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
if ( ch1 === '=' && ch2 === '>' ) {
index += 2 ;
return {
type : Token . Punctuator ,
value : '=>' ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
if ( '<>=!+-*%&|^/' . indexOf ( ch1 ) >= 0 ) {
++ index ;
return {
type : Token . Punctuator ,
value : ch1 ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
if ( ch1 === '.' ) {
++ index ;
return {
type : Token . Punctuator ,
value : ch1 ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
// 7.8.3 Numeric Literals
function scanHexLiteral ( start ) {
var number = '' ;
while ( index < length ) {
if ( ! isHexDigit ( source [ index ] ) ) {
break ;
}
number += source [ index ++ ] ;
}
if ( number . length === 0 ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
if ( isIdentifierStart ( source . charCodeAt ( index ) ) ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
return {
type : Token . NumericLiteral ,
value : parseInt ( '0x' + number , 16 ) ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
function scanOctalLiteral ( prefix , start ) {
var number , octal ;
if ( isOctalDigit ( prefix ) ) {
octal = true ;
number = '0' + source [ index ++ ] ;
} else {
octal = false ;
++ index ;
number = '' ;
}
while ( index < length ) {
if ( ! isOctalDigit ( source [ index ] ) ) {
break ;
}
number += source [ index ++ ] ;
}
if ( ! octal && number . length === 0 ) {
// only 0o or 0O
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
if ( isIdentifierStart ( source . charCodeAt ( index ) ) || isDecimalDigit ( source . charCodeAt ( index ) ) ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
return {
type : Token . NumericLiteral ,
value : parseInt ( number , 8 ) ,
octal : octal ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
function scanNumericLiteral ( ) {
var number , start , ch , octal ;
ch = source [ index ] ;
assert ( isDecimalDigit ( ch . charCodeAt ( 0 ) ) || ( ch === '.' ) ,
'Numeric literal must start with a decimal digit or a decimal point' ) ;
start = index ;
number = '' ;
if ( ch !== '.' ) {
number = source [ index ++ ] ;
ch = source [ index ] ;
// Hex number starts with '0x'.
// Octal number starts with '0'.
// Octal number in ES6 starts with '0o'.
// Binary number in ES6 starts with '0b'.
if ( number === '0' ) {
if ( ch === 'x' || ch === 'X' ) {
++ index ;
return scanHexLiteral ( start ) ;
}
if ( ch === 'b' || ch === 'B' ) {
++ index ;
number = '' ;
while ( index < length ) {
ch = source [ index ] ;
if ( ch !== '0' && ch !== '1' ) {
break ;
}
number += source [ index ++ ] ;
}
if ( number . length === 0 ) {
// only 0b or 0B
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
if ( index < length ) {
ch = source . charCodeAt ( index ) ;
if ( isIdentifierStart ( ch ) || isDecimalDigit ( ch ) ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
}
return {
type : Token . NumericLiteral ,
value : parseInt ( number , 2 ) ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
if ( ch === 'o' || ch === 'O' || isOctalDigit ( ch ) ) {
return scanOctalLiteral ( ch , start ) ;
}
// decimal number starts with '0' such as '09' is illegal.
if ( ch && isDecimalDigit ( ch . charCodeAt ( 0 ) ) ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
}
while ( isDecimalDigit ( source . charCodeAt ( index ) ) ) {
number += source [ index ++ ] ;
}
ch = source [ index ] ;
}
if ( ch === '.' ) {
number += source [ index ++ ] ;
while ( isDecimalDigit ( source . charCodeAt ( index ) ) ) {
number += source [ index ++ ] ;
}
ch = source [ index ] ;
}
if ( ch === 'e' || ch === 'E' ) {
number += source [ index ++ ] ;
ch = source [ index ] ;
if ( ch === '+' || ch === '-' ) {
number += source [ index ++ ] ;
}
if ( isDecimalDigit ( source . charCodeAt ( index ) ) ) {
while ( isDecimalDigit ( source . charCodeAt ( index ) ) ) {
number += source [ index ++ ] ;
}
} else {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
}
if ( isIdentifierStart ( source . charCodeAt ( index ) ) ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
return {
type : Token . NumericLiteral ,
value : parseFloat ( number ) ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
// 7.8.4 String Literals
function scanStringLiteral ( ) {
var str = '' , quote , start , ch , code , unescaped , restore , octal = false ;
quote = source [ index ] ;
assert ( ( quote === '\'' || quote === '"' ) ,
'String literal must starts with a quote' ) ;
start = index ;
++ index ;
while ( index < length ) {
ch = source [ index ++ ] ;
if ( ch === quote ) {
quote = '' ;
break ;
} else if ( ch === '\\' ) {
ch = source [ index ++ ] ;
if ( ! ch || ! isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
switch ( ch ) {
case 'n' :
str += '\n' ;
break ;
case 'r' :
str += '\r' ;
break ;
case 't' :
str += '\t' ;
break ;
case 'u' :
case 'x' :
if ( source [ index ] === '{' ) {
++ index ;
str += scanUnicodeCodePointEscape ( ) ;
} else {
restore = index ;
unescaped = scanHexEscape ( ch ) ;
if ( unescaped ) {
str += unescaped ;
} else {
index = restore ;
str += ch ;
}
}
break ;
case 'b' :
str += '\b' ;
break ;
case 'f' :
str += '\f' ;
break ;
case 'v' :
str += '\x0B' ;
break ;
default :
if ( isOctalDigit ( ch ) ) {
code = '01234567' . indexOf ( ch ) ;
// \0 is not octal escape sequence
if ( code !== 0 ) {
octal = true ;
}
if ( index < length && isOctalDigit ( source [ index ] ) ) {
octal = true ;
code = code * 8 + '01234567' . indexOf ( source [ index ++ ] ) ;
// 3 digits are only allowed when string starts
// with 0, 1, 2, 3
if ( '0123' . indexOf ( ch ) >= 0 &&
index < length &&
isOctalDigit ( source [ index ] ) ) {
code = code * 8 + '01234567' . indexOf ( source [ index ++ ] ) ;
}
}
str += String . fromCharCode ( code ) ;
} else {
str += ch ;
}
break ;
}
} else {
++ lineNumber ;
if ( ch === '\r' && source [ index ] === '\n' ) {
++ index ;
}
}
} else if ( isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
break ;
} else {
str += ch ;
}
}
if ( quote !== '' ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
return {
type : Token . StringLiteral ,
value : str ,
octal : octal ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
function scanTemplate ( ) {
var cooked = '' , ch , start , terminated , tail , restore , unescaped , code , octal ;
terminated = false ;
tail = false ;
start = index ;
++ index ;
while ( index < length ) {
ch = source [ index ++ ] ;
if ( ch === '`' ) {
tail = true ;
terminated = true ;
break ;
} else if ( ch === '$' ) {
if ( source [ index ] === '{' ) {
++ index ;
terminated = true ;
break ;
}
cooked += ch ;
} else if ( ch === '\\' ) {
ch = source [ index ++ ] ;
if ( ! isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
switch ( ch ) {
case 'n' :
cooked += '\n' ;
break ;
case 'r' :
cooked += '\r' ;
break ;
case 't' :
cooked += '\t' ;
break ;
case 'u' :
case 'x' :
if ( source [ index ] === '{' ) {
++ index ;
cooked += scanUnicodeCodePointEscape ( ) ;
} else {
restore = index ;
unescaped = scanHexEscape ( ch ) ;
if ( unescaped ) {
cooked += unescaped ;
} else {
index = restore ;
cooked += ch ;
}
}
break ;
case 'b' :
cooked += '\b' ;
break ;
case 'f' :
cooked += '\f' ;
break ;
case 'v' :
cooked += '\v' ;
break ;
default :
if ( isOctalDigit ( ch ) ) {
code = '01234567' . indexOf ( ch ) ;
// \0 is not octal escape sequence
if ( code !== 0 ) {
octal = true ;
}
if ( index < length && isOctalDigit ( source [ index ] ) ) {
octal = true ;
code = code * 8 + '01234567' . indexOf ( source [ index ++ ] ) ;
// 3 digits are only allowed when string starts
// with 0, 1, 2, 3
if ( '0123' . indexOf ( ch ) >= 0 &&
index < length &&
isOctalDigit ( source [ index ] ) ) {
code = code * 8 + '01234567' . indexOf ( source [ index ++ ] ) ;
}
}
cooked += String . fromCharCode ( code ) ;
} else {
cooked += ch ;
}
break ;
}
} else {
++ lineNumber ;
if ( ch === '\r' && source [ index ] === '\n' ) {
++ index ;
}
}
} else if ( isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
++ lineNumber ;
if ( ch === '\r' && source [ index ] === '\n' ) {
++ index ;
}
cooked += '\n' ;
} else {
cooked += ch ;
}
}
if ( ! terminated ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
return {
type : Token . Template ,
value : {
cooked : cooked ,
raw : source . slice ( start + 1 , index - ( ( tail ) ? 1 : 2 ) )
} ,
tail : tail ,
octal : octal ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
function scanTemplateElement ( option ) {
var startsWith , template ;
lookahead = null ;
skipComment ( ) ;
startsWith = ( option . head ) ? '`' : '}' ;
if ( source [ index ] !== startsWith ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
template = scanTemplate ( ) ;
peek ( ) ;
return template ;
}
function scanRegExp ( ) {
var str , ch , start , pattern , flags , value , classMarker = false , restore , terminated = false ;
lookahead = null ;
skipComment ( ) ;
start = index ;
ch = source [ index ] ;
assert ( ch === '/' , 'Regular expression literal must start with a slash' ) ;
str = source [ index ++ ] ;
while ( index < length ) {
ch = source [ index ++ ] ;
str += ch ;
if ( classMarker ) {
if ( ch === ']' ) {
classMarker = false ;
}
} else {
if ( ch === '\\' ) {
ch = source [ index ++ ] ;
// ECMA-262 7.8.5
if ( isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
throwError ( { } , Messages . UnterminatedRegExp ) ;
}
str += ch ;
} else if ( ch === '/' ) {
terminated = true ;
break ;
} else if ( ch === '[' ) {
classMarker = true ;
} else if ( isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
throwError ( { } , Messages . UnterminatedRegExp ) ;
}
}
}
if ( ! terminated ) {
throwError ( { } , Messages . UnterminatedRegExp ) ;
}
// Exclude leading and trailing slash.
pattern = str . substr ( 1 , str . length - 2 ) ;
flags = '' ;
while ( index < length ) {
ch = source [ index ] ;
if ( ! isIdentifierPart ( ch . charCodeAt ( 0 ) ) ) {
break ;
}
++ index ;
if ( ch === '\\' && index < length ) {
ch = source [ index ] ;
if ( ch === 'u' ) {
++ index ;
restore = index ;
ch = scanHexEscape ( 'u' ) ;
if ( ch ) {
flags += ch ;
for ( str += '\\u' ; restore < index ; ++ restore ) {
str += source [ restore ] ;
}
} else {
index = restore ;
flags += 'u' ;
str += '\\u' ;
}
} else {
str += '\\' ;
}
} else {
flags += ch ;
str += ch ;
}
}
try {
value = new RegExp ( pattern , flags ) ;
} catch ( e ) {
throwError ( { } , Messages . InvalidRegExp ) ;
}
peek ( ) ;
if ( extra . tokenize ) {
return {
type : Token . RegularExpression ,
value : value ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
return {
literal : str ,
value : value ,
range : [ start , index ]
} ;
}
function isIdentifierName ( token ) {
return token . type === Token . Identifier ||
token . type === Token . Keyword ||
token . type === Token . BooleanLiteral ||
token . type === Token . NullLiteral ;
}
function advanceSlash ( ) {
var prevToken ,
checkToken ;
// Using the following algorithm:
// https://github.com/mozilla/sweet.js/wiki/design
prevToken = extra . tokens [ extra . tokens . length - 1 ] ;
if ( ! prevToken ) {
// Nothing before that: it cannot be a division.
return scanRegExp ( ) ;
}
if ( prevToken . type === "Punctuator" ) {
if ( prevToken . value === ")" ) {
checkToken = extra . tokens [ extra . openParenToken - 1 ] ;
if ( checkToken &&
checkToken . type === "Keyword" &&
( checkToken . value === "if" ||
checkToken . value === "while" ||
checkToken . value === "for" ||
checkToken . value === "with" ) ) {
return scanRegExp ( ) ;
}
return scanPunctuator ( ) ;
}
if ( prevToken . value === "}" ) {
// Dividing a function by anything makes little sense,
// but we have to check for that.
if ( extra . tokens [ extra . openCurlyToken - 3 ] &&
extra . tokens [ extra . openCurlyToken - 3 ] . type === "Keyword" ) {
// Anonymous function.
checkToken = extra . tokens [ extra . openCurlyToken - 4 ] ;
if ( ! checkToken ) {
return scanPunctuator ( ) ;
}
} else if ( extra . tokens [ extra . openCurlyToken - 4 ] &&
extra . tokens [ extra . openCurlyToken - 4 ] . type === "Keyword" ) {
// Named function.
checkToken = extra . tokens [ extra . openCurlyToken - 5 ] ;
if ( ! checkToken ) {
return scanRegExp ( ) ;
}
} else {
return scanPunctuator ( ) ;
}
// checkToken determines whether the function is
// a declaration or an expression.
if ( FnExprTokens . indexOf ( checkToken . value ) >= 0 ) {
// It is an expression.
return scanPunctuator ( ) ;
}
// It is a declaration.
return scanRegExp ( ) ;
}
return scanRegExp ( ) ;
}
if ( prevToken . type === "Keyword" ) {
return scanRegExp ( ) ;
}
return scanPunctuator ( ) ;
}
function advance ( ) {
var ch ;
if ( state . inXJSChild ) {
return advanceXJSChild ( ) ;
}
skipComment ( ) ;
if ( index >= length ) {
return {
type : Token . EOF ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ index , index ]
} ;
}
ch = source . charCodeAt ( index ) ;
// Very common: ( and ) and ;
if ( ch === 40 || ch === 41 || ch === 58 ) {
return scanPunctuator ( ) ;
}
// String literal starts with single quote (#39) or double quote (#34).
if ( ch === 39 || ch === 34 ) {
if ( state . inXJSTag ) {
return scanXJSStringLiteral ( ) ;
}
return scanStringLiteral ( ) ;
}
if ( state . inXJSTag && isXJSIdentifierStart ( ch ) ) {
return scanXJSIdentifier ( ) ;
}
if ( ch === 96 ) {
return scanTemplate ( ) ;
}
if ( isIdentifierStart ( ch ) ) {
return scanIdentifier ( ) ;
}
// Dot (.) char #46 can also start a floating-point number, hence the need
// to check the next character.
if ( ch === 46 ) {
if ( isDecimalDigit ( source . charCodeAt ( index + 1 ) ) ) {
return scanNumericLiteral ( ) ;
}
return scanPunctuator ( ) ;
}
if ( isDecimalDigit ( ch ) ) {
return scanNumericLiteral ( ) ;
}
// Slash (/) char #47 can also start a regex.
if ( extra . tokenize && ch === 47 ) {
return advanceSlash ( ) ;
}
return scanPunctuator ( ) ;
}
function lex ( ) {
var token ;
token = lookahead ;
index = token . range [ 1 ] ;
lineNumber = token . lineNumber ;
lineStart = token . lineStart ;
lookahead = advance ( ) ;
index = token . range [ 1 ] ;
lineNumber = token . lineNumber ;
lineStart = token . lineStart ;
return token ;
}
function peek ( ) {
var pos , line , start ;
pos = index ;
line = lineNumber ;
start = lineStart ;
lookahead = advance ( ) ;
index = pos ;
lineNumber = line ;
lineStart = start ;
}
function lookahead2 ( ) {
var adv , pos , line , start , result ;
// If we are collecting the tokens, don't grab the next one yet.
adv = ( typeof extra . advance === 'function' ) ? extra . advance : advance ;
pos = index ;
line = lineNumber ;
start = lineStart ;
// Scan for the next immediate token.
if ( lookahead === null ) {
lookahead = adv ( ) ;
}
index = lookahead . range [ 1 ] ;
lineNumber = lookahead . lineNumber ;
lineStart = lookahead . lineStart ;
// Grab the token right after.
result = adv ( ) ;
index = pos ;
lineNumber = line ;
lineStart = start ;
return result ;
}
SyntaxTreeDelegate = {
name : 'SyntaxTree' ,
postProcess : function ( node ) {
return node ;
} ,
createArrayExpression : function ( elements ) {
return {
type : Syntax . ArrayExpression ,
elements : elements
} ;
} ,
createAssignmentExpression : function ( operator , left , right ) {
return {
type : Syntax . AssignmentExpression ,
operator : operator ,
left : left ,
right : right
} ;
} ,
createBinaryExpression : function ( operator , left , right ) {
var type = ( operator === '||' || operator === '&&' ) ? Syntax . LogicalExpression :
Syntax . BinaryExpression ;
return {
type : type ,
operator : operator ,
left : left ,
right : right
} ;
} ,
createBlockStatement : function ( body ) {
return {
type : Syntax . BlockStatement ,
body : body
} ;
} ,
createBreakStatement : function ( label ) {
return {
type : Syntax . BreakStatement ,
label : label
} ;
} ,
createCallExpression : function ( callee , args ) {
return {
type : Syntax . CallExpression ,
callee : callee ,
'arguments' : args
} ;
} ,
createCatchClause : function ( param , body ) {
return {
type : Syntax . CatchClause ,
param : param ,
body : body
} ;
} ,
createConditionalExpression : function ( test , consequent , alternate ) {
return {
type : Syntax . ConditionalExpression ,
test : test ,
consequent : consequent ,
alternate : alternate
} ;
} ,
createContinueStatement : function ( label ) {
return {
type : Syntax . ContinueStatement ,
label : label
} ;
} ,
createDebuggerStatement : function ( ) {
return {
type : Syntax . DebuggerStatement
} ;
} ,
createDoWhileStatement : function ( body , test ) {
return {
type : Syntax . DoWhileStatement ,
body : body ,
test : test
} ;
} ,
createEmptyStatement : function ( ) {
return {
type : Syntax . EmptyStatement
} ;
} ,
createExpressionStatement : function ( expression ) {
return {
type : Syntax . ExpressionStatement ,
expression : expression
} ;
} ,
createForStatement : function ( init , test , update , body ) {
return {
type : Syntax . ForStatement ,
init : init ,
test : test ,
update : update ,
body : body
} ;
} ,
createForInStatement : function ( left , right , body ) {
return {
type : Syntax . ForInStatement ,
left : left ,
right : right ,
body : body ,
each : false
} ;
} ,
createForOfStatement : function ( left , right , body ) {
return {
type : Syntax . ForOfStatement ,
left : left ,
right : right ,
body : body ,
} ;
} ,
createFunctionDeclaration : function ( id , params , defaults , body , rest , generator , expression ,
2014-01-03 15:54:38 +00:00
returnType ) {
2013-12-16 22:19:36 +00:00
return {
type : Syntax . FunctionDeclaration ,
id : id ,
params : params ,
defaults : defaults ,
body : body ,
rest : rest ,
generator : generator ,
2014-01-03 15:54:38 +00:00
expression : expression ,
returnType : returnType
2013-12-16 22:19:36 +00:00
} ;
} ,
createFunctionExpression : function ( id , params , defaults , body , rest , generator , expression ,
2014-01-03 15:54:38 +00:00
returnType ) {
2013-12-16 22:19:36 +00:00
return {
type : Syntax . FunctionExpression ,
id : id ,
params : params ,
defaults : defaults ,
body : body ,
rest : rest ,
generator : generator ,
2014-01-03 15:54:38 +00:00
expression : expression ,
returnType : returnType
2013-12-16 22:19:36 +00:00
} ;
} ,
createIdentifier : function ( name ) {
return {
type : Syntax . Identifier ,
2014-01-03 15:54:38 +00:00
name : name ,
// Only here to initialize the shape of the object to ensure
// that the 'typeAnnotation' key is ordered before others that
// are added later (like 'loc' and 'range'). This just helps
// keep the shape of Identifier nodes consistent with everything
// else.
typeAnnotation : undefined
2013-12-16 22:19:36 +00:00
} ;
} ,
2014-01-03 15:54:38 +00:00
createTypeAnnotation : function ( typeIdentifier , paramTypes , returnType , isNullable ) {
2013-12-16 22:19:36 +00:00
return {
2014-01-03 15:54:38 +00:00
type : Syntax . TypeAnnotation ,
id : typeIdentifier ,
paramTypes : paramTypes ,
returnType : returnType ,
isNullable : isNullable
2013-12-16 22:19:36 +00:00
} ;
} ,
2014-01-03 15:54:38 +00:00
createTypeAnnotatedIdentifier : function ( identifier , annotation ) {
2013-12-16 22:19:36 +00:00
return {
2014-01-03 15:54:38 +00:00
type : Syntax . TypeAnnotatedIdentifier ,
id : identifier ,
annotation : annotation
2013-12-16 22:19:36 +00:00
} ;
} ,
createXJSAttribute : function ( name , value ) {
return {
type : Syntax . XJSAttribute ,
name : name ,
value : value
} ;
} ,
createXJSIdentifier : function ( name , namespace ) {
return {
type : Syntax . XJSIdentifier ,
name : name ,
namespace : namespace
} ;
} ,
createXJSElement : function ( openingElement , closingElement , children ) {
return {
type : Syntax . XJSElement ,
name : openingElement . name ,
selfClosing : openingElement . selfClosing ,
openingElement : openingElement ,
closingElement : closingElement ,
attributes : openingElement . attributes ,
children : children
} ;
} ,
createXJSEmptyExpression : function ( ) {
return {
type : Syntax . XJSEmptyExpression
} ;
} ,
createXJSExpressionContainer : function ( expression ) {
return {
type : Syntax . XJSExpressionContainer ,
expression : expression
} ;
} ,
createXJSOpeningElement : function ( name , attributes , selfClosing ) {
return {
type : Syntax . XJSOpeningElement ,
name : name ,
selfClosing : selfClosing ,
attributes : attributes
} ;
} ,
createXJSClosingElement : function ( name ) {
return {
type : Syntax . XJSClosingElement ,
name : name
} ;
} ,
createIfStatement : function ( test , consequent , alternate ) {
return {
type : Syntax . IfStatement ,
test : test ,
consequent : consequent ,
alternate : alternate
} ;
} ,
createLabeledStatement : function ( label , body ) {
return {
type : Syntax . LabeledStatement ,
label : label ,
body : body
} ;
} ,
createLiteral : function ( token ) {
return {
type : Syntax . Literal ,
value : token . value ,
raw : source . slice ( token . range [ 0 ] , token . range [ 1 ] )
} ;
} ,
createMemberExpression : function ( accessor , object , property ) {
return {
type : Syntax . MemberExpression ,
computed : accessor === '[' ,
object : object ,
property : property
} ;
} ,
createNewExpression : function ( callee , args ) {
return {
type : Syntax . NewExpression ,
callee : callee ,
'arguments' : args
} ;
} ,
createObjectExpression : function ( properties ) {
return {
type : Syntax . ObjectExpression ,
properties : properties
} ;
} ,
createPostfixExpression : function ( operator , argument ) {
return {
type : Syntax . UpdateExpression ,
operator : operator ,
argument : argument ,
prefix : false
} ;
} ,
createProgram : function ( body ) {
return {
type : Syntax . Program ,
body : body
} ;
} ,
createProperty : function ( kind , key , value , method , shorthand ) {
return {
type : Syntax . Property ,
key : key ,
value : value ,
kind : kind ,
method : method ,
shorthand : shorthand
} ;
} ,
createReturnStatement : function ( argument ) {
return {
type : Syntax . ReturnStatement ,
argument : argument
} ;
} ,
createSequenceExpression : function ( expressions ) {
return {
type : Syntax . SequenceExpression ,
expressions : expressions
} ;
} ,
createSwitchCase : function ( test , consequent ) {
return {
type : Syntax . SwitchCase ,
test : test ,
consequent : consequent
} ;
} ,
createSwitchStatement : function ( discriminant , cases ) {
return {
type : Syntax . SwitchStatement ,
discriminant : discriminant ,
cases : cases
} ;
} ,
createThisExpression : function ( ) {
return {
type : Syntax . ThisExpression
} ;
} ,
createThrowStatement : function ( argument ) {
return {
type : Syntax . ThrowStatement ,
argument : argument
} ;
} ,
createTryStatement : function ( block , guardedHandlers , handlers , finalizer ) {
return {
type : Syntax . TryStatement ,
block : block ,
guardedHandlers : guardedHandlers ,
handlers : handlers ,
finalizer : finalizer
} ;
} ,
createUnaryExpression : function ( operator , argument ) {
if ( operator === '++' || operator === '--' ) {
return {
type : Syntax . UpdateExpression ,
operator : operator ,
argument : argument ,
prefix : true
} ;
}
return {
type : Syntax . UnaryExpression ,
operator : operator ,
argument : argument
} ;
} ,
createVariableDeclaration : function ( declarations , kind ) {
return {
type : Syntax . VariableDeclaration ,
declarations : declarations ,
kind : kind
} ;
} ,
createVariableDeclarator : function ( id , init ) {
return {
type : Syntax . VariableDeclarator ,
id : id ,
init : init
} ;
} ,
createWhileStatement : function ( test , body ) {
return {
type : Syntax . WhileStatement ,
test : test ,
body : body
} ;
} ,
createWithStatement : function ( object , body ) {
return {
type : Syntax . WithStatement ,
object : object ,
body : body
} ;
} ,
createTemplateElement : function ( value , tail ) {
return {
type : Syntax . TemplateElement ,
value : value ,
tail : tail
} ;
} ,
createTemplateLiteral : function ( quasis , expressions ) {
return {
type : Syntax . TemplateLiteral ,
quasis : quasis ,
expressions : expressions
} ;
} ,
createSpreadElement : function ( argument ) {
return {
type : Syntax . SpreadElement ,
argument : argument
} ;
} ,
createTaggedTemplateExpression : function ( tag , quasi ) {
return {
type : Syntax . TaggedTemplateExpression ,
tag : tag ,
quasi : quasi
} ;
} ,
createArrowFunctionExpression : function ( params , defaults , body , rest , expression ) {
return {
type : Syntax . ArrowFunctionExpression ,
id : null ,
params : params ,
defaults : defaults ,
body : body ,
rest : rest ,
generator : false ,
expression : expression
} ;
} ,
createMethodDefinition : function ( propertyType , kind , key , value ) {
return {
type : Syntax . MethodDefinition ,
key : key ,
value : value ,
kind : kind ,
'static' : propertyType === ClassPropertyType . static
} ;
} ,
createClassBody : function ( body ) {
return {
type : Syntax . ClassBody ,
body : body
} ;
} ,
createClassExpression : function ( id , superClass , body ) {
return {
type : Syntax . ClassExpression ,
id : id ,
superClass : superClass ,
body : body
} ;
} ,
createClassDeclaration : function ( id , superClass , body ) {
return {
type : Syntax . ClassDeclaration ,
id : id ,
superClass : superClass ,
body : body
} ;
} ,
createExportSpecifier : function ( id , name ) {
return {
type : Syntax . ExportSpecifier ,
id : id ,
name : name
} ;
} ,
createExportBatchSpecifier : function ( ) {
return {
type : Syntax . ExportBatchSpecifier
} ;
} ,
2014-01-03 15:54:38 +00:00
createExportDeclaration : function ( declaration , specifiers , source ) {
2013-12-16 22:19:36 +00:00
return {
type : Syntax . ExportDeclaration ,
declaration : declaration ,
specifiers : specifiers ,
source : source
} ;
} ,
createImportSpecifier : function ( id , name ) {
return {
type : Syntax . ImportSpecifier ,
id : id ,
name : name
} ;
} ,
createImportDeclaration : function ( specifiers , kind , source ) {
return {
type : Syntax . ImportDeclaration ,
specifiers : specifiers ,
kind : kind ,
source : source
} ;
} ,
createYieldExpression : function ( argument , delegate ) {
return {
type : Syntax . YieldExpression ,
argument : argument ,
delegate : delegate
} ;
} ,
createModuleDeclaration : function ( id , source , body ) {
return {
type : Syntax . ModuleDeclaration ,
id : id ,
source : source ,
body : body
} ;
}
} ;
// Return true if there is a line terminator before the next token.
function peekLineTerminator ( ) {
var pos , line , start , found ;
pos = index ;
line = lineNumber ;
start = lineStart ;
skipComment ( ) ;
found = lineNumber !== line ;
index = pos ;
lineNumber = line ;
lineStart = start ;
return found ;
}
// Throw an exception
function throwError ( token , messageFormat ) {
var error ,
args = Array . prototype . slice . call ( arguments , 2 ) ,
msg = messageFormat . replace (
/%(\d)/g ,
function ( whole , index ) {
assert ( index < args . length , 'Message reference must be in range' ) ;
return args [ index ] ;
}
) ;
if ( typeof token . lineNumber === 'number' ) {
error = new Error ( 'Line ' + token . lineNumber + ': ' + msg ) ;
error . index = token . range [ 0 ] ;
error . lineNumber = token . lineNumber ;
error . column = token . range [ 0 ] - lineStart + 1 ;
} else {
error = new Error ( 'Line ' + lineNumber + ': ' + msg ) ;
error . index = index ;
error . lineNumber = lineNumber ;
error . column = index - lineStart + 1 ;
}
error . description = msg ;
throw error ;
}
function throwErrorTolerant ( ) {
try {
throwError . apply ( null , arguments ) ;
} catch ( e ) {
if ( extra . errors ) {
extra . errors . push ( e ) ;
} else {
throw e ;
}
}
}
// Throw an exception because of the token.
function throwUnexpected ( token ) {
if ( token . type === Token . EOF ) {
throwError ( token , Messages . UnexpectedEOS ) ;
}
if ( token . type === Token . NumericLiteral ) {
throwError ( token , Messages . UnexpectedNumber ) ;
}
if ( token . type === Token . StringLiteral ) {
throwError ( token , Messages . UnexpectedString ) ;
}
if ( token . type === Token . Identifier ) {
throwError ( token , Messages . UnexpectedIdentifier ) ;
}
if ( token . type === Token . Keyword ) {
if ( isFutureReservedWord ( token . value ) ) {
throwError ( token , Messages . UnexpectedReserved ) ;
} else if ( strict && isStrictModeReservedWord ( token . value ) ) {
throwErrorTolerant ( token , Messages . StrictReservedWord ) ;
return ;
}
throwError ( token , Messages . UnexpectedToken , token . value ) ;
}
if ( token . type === Token . Template ) {
throwError ( token , Messages . UnexpectedTemplate , token . value . raw ) ;
}
// BooleanLiteral, NullLiteral, or Punctuator.
throwError ( token , Messages . UnexpectedToken , token . value ) ;
}
// Expect the next token to match the specified punctuator.
// If not, an exception will be thrown.
function expect ( value ) {
var token = lex ( ) ;
if ( token . type !== Token . Punctuator || token . value !== value ) {
throwUnexpected ( token ) ;
}
}
// Expect the next token to match the specified keyword.
// If not, an exception will be thrown.
function expectKeyword ( keyword ) {
var token = lex ( ) ;
if ( token . type !== Token . Keyword || token . value !== keyword ) {
throwUnexpected ( token ) ;
}
}
// Return true if the next token matches the specified punctuator.
function match ( value ) {
return lookahead . type === Token . Punctuator && lookahead . value === value ;
}
// Return true if the next token matches the specified keyword
function matchKeyword ( keyword ) {
return lookahead . type === Token . Keyword && lookahead . value === keyword ;
}
// Return true if the next token matches the specified contextual keyword
function matchContextualKeyword ( keyword ) {
return lookahead . type === Token . Identifier && lookahead . value === keyword ;
}
// Return true if the next token is an assignment operator
function matchAssign ( ) {
var op ;
if ( lookahead . type !== Token . Punctuator ) {
return false ;
}
op = lookahead . value ;
return op === '=' ||
op === '*=' ||
op === '/=' ||
op === '%=' ||
op === '+=' ||
op === '-=' ||
op === '<<=' ||
op === '>>=' ||
op === '>>>=' ||
op === '&=' ||
op === '^=' ||
op === '|=' ;
}
function consumeSemicolon ( ) {
var line ;
// Catch the very common case first: immediately a semicolon (char #59).
if ( source . charCodeAt ( index ) === 59 ) {
lex ( ) ;
return ;
}
line = lineNumber ;
skipComment ( ) ;
if ( lineNumber !== line ) {
return ;
}
if ( match ( ';' ) ) {
lex ( ) ;
return ;
}
if ( lookahead . type !== Token . EOF && ! match ( '}' ) ) {
throwUnexpected ( lookahead ) ;
}
}
// Return true if provided expression is LeftHandSideExpression
function isLeftHandSide ( expr ) {
return expr . type === Syntax . Identifier || expr . type === Syntax . MemberExpression ;
}
function isAssignableLeftHandSide ( expr ) {
return isLeftHandSide ( expr ) || expr . type === Syntax . ObjectPattern || expr . type === Syntax . ArrayPattern ;
}
// 11.1.4 Array Initialiser
function parseArrayInitialiser ( ) {
var elements = [ ] , blocks = [ ] , filter = null , tmp , possiblecomprehension = true , body ;
expect ( '[' ) ;
while ( ! match ( ']' ) ) {
if ( lookahead . value === 'for' &&
lookahead . type === Token . Keyword ) {
if ( ! possiblecomprehension ) {
throwError ( { } , Messages . ComprehensionError ) ;
}
matchKeyword ( 'for' ) ;
tmp = parseForStatement ( { ignore _body : true } ) ;
tmp . of = tmp . type === Syntax . ForOfStatement ;
tmp . type = Syntax . ComprehensionBlock ;
if ( tmp . left . kind ) { // can't be let or const
throwError ( { } , Messages . ComprehensionError ) ;
}
blocks . push ( tmp ) ;
} else if ( lookahead . value === 'if' &&
lookahead . type === Token . Keyword ) {
if ( ! possiblecomprehension ) {
throwError ( { } , Messages . ComprehensionError ) ;
}
expectKeyword ( 'if' ) ;
expect ( '(' ) ;
filter = parseExpression ( ) ;
expect ( ')' ) ;
} else if ( lookahead . value === ',' &&
lookahead . type === Token . Punctuator ) {
possiblecomprehension = false ; // no longer allowed.
lex ( ) ;
elements . push ( null ) ;
} else {
tmp = parseSpreadOrAssignmentExpression ( ) ;
elements . push ( tmp ) ;
if ( tmp && tmp . type === Syntax . SpreadElement ) {
if ( ! match ( ']' ) ) {
throwError ( { } , Messages . ElementAfterSpreadElement ) ;
}
} else if ( ! ( match ( ']' ) || matchKeyword ( 'for' ) || matchKeyword ( 'if' ) ) ) {
expect ( ',' ) ; // this lexes.
possiblecomprehension = false ;
}
}
}
expect ( ']' ) ;
if ( filter && ! blocks . length ) {
throwError ( { } , Messages . ComprehensionRequiresBlock ) ;
}
if ( blocks . length ) {
if ( elements . length !== 1 ) {
throwError ( { } , Messages . ComprehensionError ) ;
}
return {
type : Syntax . ComprehensionExpression ,
filter : filter ,
blocks : blocks ,
body : elements [ 0 ]
} ;
}
return delegate . createArrayExpression ( elements ) ;
}
// 11.1.5 Object Initialiser
function parsePropertyFunction ( options ) {
var previousStrict , previousYieldAllowed , params , defaults , body ;
previousStrict = strict ;
previousYieldAllowed = state . yieldAllowed ;
state . yieldAllowed = options . generator ;
params = options . params || [ ] ;
defaults = options . defaults || [ ] ;
body = parseConciseBody ( ) ;
if ( options . name && strict && isRestrictedWord ( params [ 0 ] . name ) ) {
throwErrorTolerant ( options . name , Messages . StrictParamName ) ;
}
if ( state . yieldAllowed && ! state . yieldFound ) {
throwErrorTolerant ( { } , Messages . NoYieldInGenerator ) ;
}
strict = previousStrict ;
state . yieldAllowed = previousYieldAllowed ;
return delegate . createFunctionExpression ( null , params , defaults , body , options . rest || null , options . generator , body . type !== Syntax . BlockStatement ,
options . returnTypeAnnotation ) ;
}
function parsePropertyMethodFunction ( options ) {
var previousStrict , tmp , method ;
previousStrict = strict ;
strict = true ;
tmp = parseParams ( ) ;
if ( tmp . stricted ) {
throwErrorTolerant ( tmp . stricted , tmp . message ) ;
}
method = parsePropertyFunction ( {
params : tmp . params ,
defaults : tmp . defaults ,
rest : tmp . rest ,
generator : options . generator ,
returnTypeAnnotation : tmp . returnTypeAnnotation
} ) ;
strict = previousStrict ;
return method ;
}
function parseObjectPropertyKey ( ) {
var token = lex ( ) ;
// Note: This function is called only from parseObjectProperty(), where
// EOF and Punctuator tokens are already filtered out.
if ( token . type === Token . StringLiteral || token . type === Token . NumericLiteral ) {
if ( strict && token . octal ) {
throwErrorTolerant ( token , Messages . StrictOctalLiteral ) ;
}
return delegate . createLiteral ( token ) ;
}
return delegate . createIdentifier ( token . value ) ;
}
function parseObjectProperty ( ) {
var token , key , id , value , param ;
token = lookahead ;
if ( token . type === Token . Identifier ) {
id = parseObjectPropertyKey ( ) ;
// Property Assignment: Getter and Setter.
if ( token . value === 'get' && ! ( match ( ':' ) || match ( '(' ) ) ) {
key = parseObjectPropertyKey ( ) ;
expect ( '(' ) ;
expect ( ')' ) ;
return delegate . createProperty ( 'get' , key , parsePropertyFunction ( { generator : false } ) , false , false ) ;
}
if ( token . value === 'set' && ! ( match ( ':' ) || match ( '(' ) ) ) {
key = parseObjectPropertyKey ( ) ;
expect ( '(' ) ;
token = lookahead ;
2014-01-03 15:54:38 +00:00
param = [ parseTypeAnnotatableIdentifier ( ) ] ;
2013-12-16 22:19:36 +00:00
expect ( ')' ) ;
return delegate . createProperty ( 'set' , key , parsePropertyFunction ( { params : param , generator : false , name : token } ) , false , false ) ;
}
if ( match ( ':' ) ) {
lex ( ) ;
return delegate . createProperty ( 'init' , id , parseAssignmentExpression ( ) , false , false ) ;
}
if ( match ( '(' ) ) {
return delegate . createProperty ( 'init' , id , parsePropertyMethodFunction ( { generator : false } ) , true , false ) ;
}
return delegate . createProperty ( 'init' , id , id , false , true ) ;
}
if ( token . type === Token . EOF || token . type === Token . Punctuator ) {
if ( ! match ( '*' ) ) {
throwUnexpected ( token ) ;
}
lex ( ) ;
id = parseObjectPropertyKey ( ) ;
if ( ! match ( '(' ) ) {
throwUnexpected ( lex ( ) ) ;
}
return delegate . createProperty ( 'init' , id , parsePropertyMethodFunction ( { generator : true } ) , true , false ) ;
}
key = parseObjectPropertyKey ( ) ;
if ( match ( ':' ) ) {
lex ( ) ;
return delegate . createProperty ( 'init' , key , parseAssignmentExpression ( ) , false , false ) ;
}
if ( match ( '(' ) ) {
return delegate . createProperty ( 'init' , key , parsePropertyMethodFunction ( { generator : false } ) , true , false ) ;
}
throwUnexpected ( lex ( ) ) ;
}
function parseObjectInitialiser ( ) {
var properties = [ ] , property , name , key , kind , map = { } , toString = String ;
expect ( '{' ) ;
while ( ! match ( '}' ) ) {
property = parseObjectProperty ( ) ;
if ( property . key . type === Syntax . Identifier ) {
name = property . key . name ;
} else {
name = toString ( property . key . value ) ;
}
kind = ( property . kind === 'init' ) ? PropertyKind . Data : ( property . kind === 'get' ) ? PropertyKind . Get : PropertyKind . Set ;
key = '$' + name ;
if ( Object . prototype . hasOwnProperty . call ( map , key ) ) {
if ( map [ key ] === PropertyKind . Data ) {
if ( strict && kind === PropertyKind . Data ) {
throwErrorTolerant ( { } , Messages . StrictDuplicateProperty ) ;
} else if ( kind !== PropertyKind . Data ) {
throwErrorTolerant ( { } , Messages . AccessorDataProperty ) ;
}
} else {
if ( kind === PropertyKind . Data ) {
throwErrorTolerant ( { } , Messages . AccessorDataProperty ) ;
} else if ( map [ key ] & kind ) {
throwErrorTolerant ( { } , Messages . AccessorGetSet ) ;
}
}
map [ key ] |= kind ;
} else {
map [ key ] = kind ;
}
properties . push ( property ) ;
if ( ! match ( '}' ) ) {
expect ( ',' ) ;
}
}
expect ( '}' ) ;
return delegate . createObjectExpression ( properties ) ;
}
function parseTemplateElement ( option ) {
var token = scanTemplateElement ( option ) ;
if ( strict && token . octal ) {
throwError ( token , Messages . StrictOctalLiteral ) ;
}
return delegate . createTemplateElement ( { raw : token . value . raw , cooked : token . value . cooked } , token . tail ) ;
}
function parseTemplateLiteral ( ) {
var quasi , quasis , expressions ;
quasi = parseTemplateElement ( { head : true } ) ;
quasis = [ quasi ] ;
expressions = [ ] ;
while ( ! quasi . tail ) {
expressions . push ( parseExpression ( ) ) ;
quasi = parseTemplateElement ( { head : false } ) ;
quasis . push ( quasi ) ;
}
return delegate . createTemplateLiteral ( quasis , expressions ) ;
}
// 11.1.6 The Grouping Operator
function parseGroupExpression ( ) {
var expr ;
expect ( '(' ) ;
++ state . parenthesizedCount ;
state . allowArrowFunction = ! state . allowArrowFunction ;
expr = parseExpression ( ) ;
state . allowArrowFunction = false ;
if ( expr . type !== Syntax . ArrowFunctionExpression ) {
expect ( ')' ) ;
}
return expr ;
}
// 11.1 Primary Expressions
function parsePrimaryExpression ( ) {
var type , token ;
token = lookahead ;
type = lookahead . type ;
if ( type === Token . Identifier ) {
lex ( ) ;
return delegate . createIdentifier ( token . value ) ;
}
if ( type === Token . StringLiteral || type === Token . NumericLiteral ) {
if ( strict && lookahead . octal ) {
throwErrorTolerant ( lookahead , Messages . StrictOctalLiteral ) ;
}
return delegate . createLiteral ( lex ( ) ) ;
}
if ( type === Token . Keyword ) {
if ( matchKeyword ( 'this' ) ) {
lex ( ) ;
return delegate . createThisExpression ( ) ;
}
if ( matchKeyword ( 'function' ) ) {
return parseFunctionExpression ( ) ;
}
if ( matchKeyword ( 'class' ) ) {
return parseClassExpression ( ) ;
}
if ( matchKeyword ( 'super' ) ) {
lex ( ) ;
return delegate . createIdentifier ( 'super' ) ;
}
}
if ( type === Token . BooleanLiteral ) {
token = lex ( ) ;
token . value = ( token . value === 'true' ) ;
return delegate . createLiteral ( token ) ;
}
if ( type === Token . NullLiteral ) {
token = lex ( ) ;
token . value = null ;
return delegate . createLiteral ( token ) ;
}
if ( match ( '[' ) ) {
return parseArrayInitialiser ( ) ;
}
if ( match ( '{' ) ) {
return parseObjectInitialiser ( ) ;
}
if ( match ( '(' ) ) {
return parseGroupExpression ( ) ;
}
if ( match ( '/' ) || match ( '/=' ) ) {
return delegate . createLiteral ( scanRegExp ( ) ) ;
}
if ( type === Token . Template ) {
return parseTemplateLiteral ( ) ;
}
if ( match ( '<' ) ) {
return parseXJSElement ( ) ;
}
return throwUnexpected ( lex ( ) ) ;
}
// 11.2 Left-Hand-Side Expressions
function parseArguments ( ) {
var args = [ ] , arg ;
expect ( '(' ) ;
if ( ! match ( ')' ) ) {
while ( index < length ) {
arg = parseSpreadOrAssignmentExpression ( ) ;
args . push ( arg ) ;
if ( match ( ')' ) ) {
break ;
} else if ( arg . type === Syntax . SpreadElement ) {
throwError ( { } , Messages . ElementAfterSpreadElement ) ;
}
expect ( ',' ) ;
}
}
expect ( ')' ) ;
return args ;
}
function parseSpreadOrAssignmentExpression ( ) {
if ( match ( '...' ) ) {
lex ( ) ;
return delegate . createSpreadElement ( parseAssignmentExpression ( ) ) ;
}
return parseAssignmentExpression ( ) ;
}
function parseNonComputedProperty ( ) {
var token = lex ( ) ;
if ( ! isIdentifierName ( token ) ) {
throwUnexpected ( token ) ;
}
return delegate . createIdentifier ( token . value ) ;
}
function parseNonComputedMember ( ) {
expect ( '.' ) ;
return parseNonComputedProperty ( ) ;
}
function parseComputedMember ( ) {
var expr ;
expect ( '[' ) ;
expr = parseExpression ( ) ;
expect ( ']' ) ;
return expr ;
}
function parseNewExpression ( ) {
var callee , args ;
expectKeyword ( 'new' ) ;
callee = parseLeftHandSideExpression ( ) ;
args = match ( '(' ) ? parseArguments ( ) : [ ] ;
return delegate . createNewExpression ( callee , args ) ;
}
function parseLeftHandSideExpressionAllowCall ( ) {
var expr , args , property ;
expr = matchKeyword ( 'new' ) ? parseNewExpression ( ) : parsePrimaryExpression ( ) ;
while ( match ( '.' ) || match ( '[' ) || match ( '(' ) || lookahead . type === Token . Template ) {
if ( match ( '(' ) ) {
args = parseArguments ( ) ;
expr = delegate . createCallExpression ( expr , args ) ;
} else if ( match ( '[' ) ) {
expr = delegate . createMemberExpression ( '[' , expr , parseComputedMember ( ) ) ;
} else if ( match ( '.' ) ) {
expr = delegate . createMemberExpression ( '.' , expr , parseNonComputedMember ( ) ) ;
} else {
expr = delegate . createTaggedTemplateExpression ( expr , parseTemplateLiteral ( ) ) ;
}
}
return expr ;
}
function parseLeftHandSideExpression ( ) {
var expr , property ;
expr = matchKeyword ( 'new' ) ? parseNewExpression ( ) : parsePrimaryExpression ( ) ;
while ( match ( '.' ) || match ( '[' ) || lookahead . type === Token . Template ) {
if ( match ( '[' ) ) {
expr = delegate . createMemberExpression ( '[' , expr , parseComputedMember ( ) ) ;
} else if ( match ( '.' ) ) {
expr = delegate . createMemberExpression ( '.' , expr , parseNonComputedMember ( ) ) ;
} else {
expr = delegate . createTaggedTemplateExpression ( expr , parseTemplateLiteral ( ) ) ;
}
}
return expr ;
}
// 11.3 Postfix Expressions
function parsePostfixExpression ( ) {
var expr = parseLeftHandSideExpressionAllowCall ( ) ,
token = lookahead ;
if ( lookahead . type !== Token . Punctuator ) {
return expr ;
}
if ( ( match ( '++' ) || match ( '--' ) ) && ! peekLineTerminator ( ) ) {
// 11.3.1, 11.3.2
if ( strict && expr . type === Syntax . Identifier && isRestrictedWord ( expr . name ) ) {
throwErrorTolerant ( { } , Messages . StrictLHSPostfix ) ;
}
if ( ! isLeftHandSide ( expr ) ) {
throwError ( { } , Messages . InvalidLHSInAssignment ) ;
}
token = lex ( ) ;
expr = delegate . createPostfixExpression ( token . value , expr ) ;
}
return expr ;
}
// 11.4 Unary Operators
function parseUnaryExpression ( ) {
var token , expr ;
if ( lookahead . type !== Token . Punctuator && lookahead . type !== Token . Keyword ) {
return parsePostfixExpression ( ) ;
}
if ( match ( '++' ) || match ( '--' ) ) {
token = lex ( ) ;
expr = parseUnaryExpression ( ) ;
// 11.4.4, 11.4.5
if ( strict && expr . type === Syntax . Identifier && isRestrictedWord ( expr . name ) ) {
throwErrorTolerant ( { } , Messages . StrictLHSPrefix ) ;
}
if ( ! isLeftHandSide ( expr ) ) {
throwError ( { } , Messages . InvalidLHSInAssignment ) ;
}
return delegate . createUnaryExpression ( token . value , expr ) ;
}
if ( match ( '+' ) || match ( '-' ) || match ( '~' ) || match ( '!' ) ) {
token = lex ( ) ;
expr = parseUnaryExpression ( ) ;
return delegate . createUnaryExpression ( token . value , expr ) ;
}
if ( matchKeyword ( 'delete' ) || matchKeyword ( 'void' ) || matchKeyword ( 'typeof' ) ) {
token = lex ( ) ;
expr = parseUnaryExpression ( ) ;
expr = delegate . createUnaryExpression ( token . value , expr ) ;
if ( strict && expr . operator === 'delete' && expr . argument . type === Syntax . Identifier ) {
throwErrorTolerant ( { } , Messages . StrictDelete ) ;
}
return expr ;
}
return parsePostfixExpression ( ) ;
}
function binaryPrecedence ( token , allowIn ) {
var prec = 0 ;
if ( token . type !== Token . Punctuator && token . type !== Token . Keyword ) {
return 0 ;
}
switch ( token . value ) {
case '||' :
prec = 1 ;
break ;
case '&&' :
prec = 2 ;
break ;
case '|' :
prec = 3 ;
break ;
case '^' :
prec = 4 ;
break ;
case '&' :
prec = 5 ;
break ;
case '==' :
case '!=' :
case '===' :
case '!==' :
prec = 6 ;
break ;
case '<' :
case '>' :
case '<=' :
case '>=' :
case 'instanceof' :
prec = 7 ;
break ;
case 'in' :
prec = allowIn ? 7 : 0 ;
break ;
case '<<' :
case '>>' :
case '>>>' :
prec = 8 ;
break ;
case '+' :
case '-' :
prec = 9 ;
break ;
case '*' :
case '/' :
case '%' :
prec = 11 ;
break ;
default :
break ;
}
return prec ;
}
// 11.5 Multiplicative Operators
// 11.6 Additive Operators
// 11.7 Bitwise Shift Operators
// 11.8 Relational Operators
// 11.9 Equality Operators
// 11.10 Binary Bitwise Operators
// 11.11 Binary Logical Operators
function parseBinaryExpression ( ) {
var expr , token , prec , previousAllowIn , stack , right , operator , left , i ;
previousAllowIn = state . allowIn ;
state . allowIn = true ;
expr = parseUnaryExpression ( ) ;
token = lookahead ;
prec = binaryPrecedence ( token , previousAllowIn ) ;
if ( prec === 0 ) {
return expr ;
}
token . prec = prec ;
lex ( ) ;
stack = [ expr , token , parseUnaryExpression ( ) ] ;
while ( ( prec = binaryPrecedence ( lookahead , previousAllowIn ) ) > 0 ) {
// Reduce: make a binary expression from the three topmost entries.
while ( ( stack . length > 2 ) && ( prec <= stack [ stack . length - 2 ] . prec ) ) {
right = stack . pop ( ) ;
operator = stack . pop ( ) . value ;
left = stack . pop ( ) ;
stack . push ( delegate . createBinaryExpression ( operator , left , right ) ) ;
}
// Shift.
token = lex ( ) ;
token . prec = prec ;
stack . push ( token ) ;
stack . push ( parseUnaryExpression ( ) ) ;
}
state . allowIn = previousAllowIn ;
// Final reduce to clean-up the stack.
i = stack . length - 1 ;
expr = stack [ i ] ;
while ( i > 1 ) {
expr = delegate . createBinaryExpression ( stack [ i - 1 ] . value , stack [ i - 2 ] , expr ) ;
i -= 2 ;
}
return expr ;
}
// 11.12 Conditional Operator
function parseConditionalExpression ( ) {
var expr , previousAllowIn , consequent , alternate ;
expr = parseBinaryExpression ( ) ;
if ( match ( '?' ) ) {
lex ( ) ;
previousAllowIn = state . allowIn ;
state . allowIn = true ;
consequent = parseAssignmentExpression ( ) ;
state . allowIn = previousAllowIn ;
expect ( ':' ) ;
alternate = parseAssignmentExpression ( ) ;
expr = delegate . createConditionalExpression ( expr , consequent , alternate ) ;
}
return expr ;
}
// 11.13 Assignment Operators
function reinterpretAsAssignmentBindingPattern ( expr ) {
var i , len , property , element ;
if ( expr . type === Syntax . ObjectExpression ) {
expr . type = Syntax . ObjectPattern ;
for ( i = 0 , len = expr . properties . length ; i < len ; i += 1 ) {
property = expr . properties [ i ] ;
if ( property . kind !== 'init' ) {
throwError ( { } , Messages . InvalidLHSInAssignment ) ;
}
reinterpretAsAssignmentBindingPattern ( property . value ) ;
}
} else if ( expr . type === Syntax . ArrayExpression ) {
expr . type = Syntax . ArrayPattern ;
for ( i = 0 , len = expr . elements . length ; i < len ; i += 1 ) {
element = expr . elements [ i ] ;
if ( element ) {
reinterpretAsAssignmentBindingPattern ( element ) ;
}
}
} else if ( expr . type === Syntax . Identifier ) {
if ( isRestrictedWord ( expr . name ) ) {
throwError ( { } , Messages . InvalidLHSInAssignment ) ;
}
} else if ( expr . type === Syntax . SpreadElement ) {
reinterpretAsAssignmentBindingPattern ( expr . argument ) ;
if ( expr . argument . type === Syntax . ObjectPattern ) {
throwError ( { } , Messages . ObjectPatternAsSpread ) ;
}
} else {
if ( expr . type !== Syntax . MemberExpression && expr . type !== Syntax . CallExpression && expr . type !== Syntax . NewExpression ) {
throwError ( { } , Messages . InvalidLHSInAssignment ) ;
}
}
}
function reinterpretAsDestructuredParameter ( options , expr ) {
var i , len , property , element ;
if ( expr . type === Syntax . ObjectExpression ) {
expr . type = Syntax . ObjectPattern ;
for ( i = 0 , len = expr . properties . length ; i < len ; i += 1 ) {
property = expr . properties [ i ] ;
if ( property . kind !== 'init' ) {
throwError ( { } , Messages . InvalidLHSInFormalsList ) ;
}
reinterpretAsDestructuredParameter ( options , property . value ) ;
}
} else if ( expr . type === Syntax . ArrayExpression ) {
expr . type = Syntax . ArrayPattern ;
for ( i = 0 , len = expr . elements . length ; i < len ; i += 1 ) {
element = expr . elements [ i ] ;
if ( element ) {
reinterpretAsDestructuredParameter ( options , element ) ;
}
}
} else if ( expr . type === Syntax . Identifier ) {
validateParam ( options , expr , expr . name ) ;
} else {
if ( expr . type !== Syntax . MemberExpression ) {
throwError ( { } , Messages . InvalidLHSInFormalsList ) ;
}
}
}
function reinterpretAsCoverFormalsList ( expressions ) {
var i , len , param , params , defaults , defaultCount , options , rest ;
params = [ ] ;
defaults = [ ] ;
defaultCount = 0 ;
rest = null ;
options = {
paramSet : { }
} ;
for ( i = 0 , len = expressions . length ; i < len ; i += 1 ) {
param = expressions [ i ] ;
if ( param . type === Syntax . Identifier ) {
params . push ( param ) ;
defaults . push ( null ) ;
validateParam ( options , param , param . name ) ;
} else if ( param . type === Syntax . ObjectExpression || param . type === Syntax . ArrayExpression ) {
reinterpretAsDestructuredParameter ( options , param ) ;
params . push ( param ) ;
defaults . push ( null ) ;
} else if ( param . type === Syntax . SpreadElement ) {
assert ( i === len - 1 , "It is guaranteed that SpreadElement is last element by parseExpression" ) ;
reinterpretAsDestructuredParameter ( options , param . argument ) ;
rest = param . argument ;
} else if ( param . type === Syntax . AssignmentExpression ) {
params . push ( param . left ) ;
defaults . push ( param . right ) ;
++ defaultCount ;
} else {
return null ;
}
}
if ( options . firstRestricted ) {
throwError ( options . firstRestricted , options . message ) ;
}
if ( options . stricted ) {
throwErrorTolerant ( options . stricted , options . message ) ;
}
if ( defaultCount === 0 ) {
defaults = [ ] ;
}
return { params : params , defaults : defaults , rest : rest } ;
}
function parseArrowFunctionExpression ( options ) {
var previousStrict , previousYieldAllowed , body ;
expect ( '=>' ) ;
previousStrict = strict ;
previousYieldAllowed = state . yieldAllowed ;
strict = true ;
state . yieldAllowed = false ;
body = parseConciseBody ( ) ;
strict = previousStrict ;
state . yieldAllowed = previousYieldAllowed ;
return delegate . createArrowFunctionExpression ( options . params , options . defaults , body , options . rest , body . type !== Syntax . BlockStatement ) ;
}
function parseAssignmentExpression ( ) {
var expr , token , params , oldParenthesizedCount ;
if ( matchKeyword ( 'yield' ) ) {
return parseYieldExpression ( ) ;
}
oldParenthesizedCount = state . parenthesizedCount ;
if ( match ( '(' ) ) {
token = lookahead2 ( ) ;
if ( ( token . type === Token . Punctuator && token . value === ')' ) || token . value === '...' ) {
params = parseParams ( ) ;
if ( ! match ( '=>' ) ) {
throwUnexpected ( lex ( ) ) ;
}
return parseArrowFunctionExpression ( params ) ;
}
}
token = lookahead ;
expr = parseConditionalExpression ( ) ;
if ( match ( '=>' ) && expr . type === Syntax . Identifier ) {
if ( state . parenthesizedCount === oldParenthesizedCount || state . parenthesizedCount === ( oldParenthesizedCount + 1 ) ) {
if ( isRestrictedWord ( expr . name ) ) {
throwError ( { } , Messages . StrictParamName ) ;
}
return parseArrowFunctionExpression ( { params : [ expr ] , defaults : [ ] , rest : null } ) ;
}
}
if ( matchAssign ( ) ) {
// 11.13.1
if ( strict && expr . type === Syntax . Identifier && isRestrictedWord ( expr . name ) ) {
throwErrorTolerant ( token , Messages . StrictLHSAssignment ) ;
}
// ES.next draf 11.13 Runtime Semantics step 1
if ( match ( '=' ) && ( expr . type === Syntax . ObjectExpression || expr . type === Syntax . ArrayExpression ) ) {
reinterpretAsAssignmentBindingPattern ( expr ) ;
} else if ( ! isLeftHandSide ( expr ) ) {
throwError ( { } , Messages . InvalidLHSInAssignment ) ;
}
expr = delegate . createAssignmentExpression ( lex ( ) . value , expr , parseAssignmentExpression ( ) ) ;
}
return expr ;
}
// 11.14 Comma Operator
function parseExpression ( ) {
var expr , expressions , sequence , coverFormalsList , spreadFound , token ;
expr = parseAssignmentExpression ( ) ;
expressions = [ expr ] ;
if ( match ( ',' ) ) {
while ( index < length ) {
if ( ! match ( ',' ) ) {
break ;
}
lex ( ) ;
expr = parseSpreadOrAssignmentExpression ( ) ;
expressions . push ( expr ) ;
if ( expr . type === Syntax . SpreadElement ) {
spreadFound = true ;
if ( ! match ( ')' ) ) {
throwError ( { } , Messages . ElementAfterSpreadElement ) ;
}
break ;
}
}
sequence = delegate . createSequenceExpression ( expressions ) ;
}
if ( state . allowArrowFunction && match ( ')' ) ) {
token = lookahead2 ( ) ;
if ( token . value === '=>' ) {
lex ( ) ;
state . allowArrowFunction = false ;
expr = expressions ;
coverFormalsList = reinterpretAsCoverFormalsList ( expr ) ;
if ( coverFormalsList ) {
return parseArrowFunctionExpression ( coverFormalsList ) ;
}
throwUnexpected ( token ) ;
}
}
if ( spreadFound ) {
throwError ( { } , Messages . IllegalSpread ) ;
}
return sequence || expr ;
}
// 12.1 Block
function parseStatementList ( ) {
var list = [ ] ,
statement ;
while ( index < length ) {
if ( match ( '}' ) ) {
break ;
}
statement = parseSourceElement ( ) ;
if ( typeof statement === 'undefined' ) {
break ;
}
list . push ( statement ) ;
}
return list ;
}
function parseBlock ( ) {
var block ;
expect ( '{' ) ;
block = parseStatementList ( ) ;
expect ( '}' ) ;
return delegate . createBlockStatement ( block ) ;
}
// 12.2 Variable Statement
2014-01-03 15:54:38 +00:00
function parseTypeAnnotation ( dontExpectColon ) {
var typeIdentifier = null , paramTypes = null , returnType = null ,
isNullable = false ;
2013-12-16 22:19:36 +00:00
2014-01-03 15:54:38 +00:00
if ( ! dontExpectColon ) {
expect ( ':' ) ;
2013-12-16 22:19:36 +00:00
}
if ( match ( '?' ) ) {
lex ( ) ;
isNullable = true ;
}
2014-01-03 15:54:38 +00:00
if ( lookahead . type === Token . Identifier ) {
typeIdentifier = parseVariableIdentifier ( ) ;
2013-12-16 22:19:36 +00:00
}
if ( match ( '(' ) ) {
lex ( ) ;
paramTypes = [ ] ;
while ( lookahead . type === Token . Identifier || match ( '?' ) ) {
2014-01-03 15:54:38 +00:00
paramTypes . push ( parseTypeAnnotation ( true ) ) ;
2013-12-16 22:19:36 +00:00
if ( ! match ( ')' ) ) {
expect ( ',' ) ;
}
}
expect ( ')' ) ;
2014-01-03 15:54:38 +00:00
expect ( '=>' ) ;
2013-12-16 22:19:36 +00:00
2014-01-03 15:54:38 +00:00
if ( matchKeyword ( 'void' ) ) {
2013-12-16 22:19:36 +00:00
lex ( ) ;
2014-01-03 15:54:38 +00:00
} else {
returnType = parseTypeAnnotation ( true ) ;
2013-12-16 22:19:36 +00:00
}
}
return delegate . createTypeAnnotation (
2014-01-03 15:54:38 +00:00
typeIdentifier ,
2013-12-16 22:19:36 +00:00
paramTypes ,
returnType ,
isNullable
) ;
}
2014-01-03 15:54:38 +00:00
function parseVariableIdentifier ( ) {
var token = lex ( ) ;
2013-12-16 22:19:36 +00:00
2014-01-03 15:54:38 +00:00
if ( token . type !== Token . Identifier ) {
throwUnexpected ( token ) ;
2013-12-16 22:19:36 +00:00
}
2014-01-03 15:54:38 +00:00
return delegate . createIdentifier ( token . value ) ;
}
2013-12-16 22:19:36 +00:00
2014-01-03 15:54:38 +00:00
function parseTypeAnnotatableIdentifier ( ) {
var ident = parseVariableIdentifier ( ) ;
2013-12-16 22:19:36 +00:00
2014-01-03 15:54:38 +00:00
if ( match ( ':' ) ) {
return delegate . createTypeAnnotatedIdentifier ( ident , parseTypeAnnotation ( ) ) ;
2013-12-16 22:19:36 +00:00
}
2014-01-03 15:54:38 +00:00
return ident ;
2013-12-16 22:19:36 +00:00
}
function parseVariableDeclaration ( kind ) {
var id ,
init = null ;
if ( match ( '{' ) ) {
id = parseObjectInitialiser ( ) ;
reinterpretAsAssignmentBindingPattern ( id ) ;
} else if ( match ( '[' ) ) {
id = parseArrayInitialiser ( ) ;
reinterpretAsAssignmentBindingPattern ( id ) ;
} else {
2014-01-03 15:54:38 +00:00
id = state . allowKeyword ? parseNonComputedProperty ( ) : parseTypeAnnotatableIdentifier ( ) ;
2013-12-16 22:19:36 +00:00
// 12.2.1
if ( strict && isRestrictedWord ( id . name ) ) {
throwErrorTolerant ( { } , Messages . StrictVarName ) ;
}
}
if ( kind === 'const' ) {
if ( ! match ( '=' ) ) {
throwError ( { } , Messages . NoUnintializedConst ) ;
}
expect ( '=' ) ;
init = parseAssignmentExpression ( ) ;
} else if ( match ( '=' ) ) {
lex ( ) ;
init = parseAssignmentExpression ( ) ;
}
return delegate . createVariableDeclarator ( id , init ) ;
}
function parseVariableDeclarationList ( kind ) {
var list = [ ] ;
do {
list . push ( parseVariableDeclaration ( kind ) ) ;
if ( ! match ( ',' ) ) {
break ;
}
lex ( ) ;
} while ( index < length ) ;
return list ;
}
function parseVariableStatement ( ) {
var declarations ;
expectKeyword ( 'var' ) ;
declarations = parseVariableDeclarationList ( ) ;
consumeSemicolon ( ) ;
return delegate . createVariableDeclaration ( declarations , 'var' ) ;
}
// kind may be `const` or `let`
// Both are experimental and not in the specification yet.
// see http://wiki.ecmascript.org/doku.php?id=harmony:const
// and http://wiki.ecmascript.org/doku.php?id=harmony:let
function parseConstLetDeclaration ( kind ) {
var declarations ;
expectKeyword ( kind ) ;
declarations = parseVariableDeclarationList ( kind ) ;
consumeSemicolon ( ) ;
return delegate . createVariableDeclaration ( declarations , kind ) ;
}
// http://wiki.ecmascript.org/doku.php?id=harmony:modules
function parseModuleDeclaration ( ) {
var id , src , body ;
lex ( ) ; // 'module'
if ( peekLineTerminator ( ) ) {
throwError ( { } , Messages . NewlineAfterModule ) ;
}
switch ( lookahead . type ) {
case Token . StringLiteral :
id = parsePrimaryExpression ( ) ;
body = parseModuleBlock ( ) ;
src = null ;
break ;
case Token . Identifier :
id = parseVariableIdentifier ( ) ;
body = null ;
if ( ! matchContextualKeyword ( 'from' ) ) {
throwUnexpected ( lex ( ) ) ;
}
lex ( ) ;
src = parsePrimaryExpression ( ) ;
if ( src . type !== Syntax . Literal ) {
throwError ( { } , Messages . InvalidModuleSpecifier ) ;
}
break ;
}
consumeSemicolon ( ) ;
return delegate . createModuleDeclaration ( id , src , body ) ;
}
function parseExportBatchSpecifier ( ) {
expect ( '*' ) ;
return delegate . createExportBatchSpecifier ( ) ;
}
function parseExportSpecifier ( ) {
var id , name = null ;
id = parseVariableIdentifier ( ) ;
if ( matchContextualKeyword ( 'as' ) ) {
lex ( ) ;
name = parseNonComputedProperty ( ) ;
}
return delegate . createExportSpecifier ( id , name ) ;
}
function parseExportDeclaration ( ) {
2014-01-03 15:54:38 +00:00
var previousAllowKeyword , decl , def , src , specifiers ;
2013-12-16 22:19:36 +00:00
expectKeyword ( 'export' ) ;
if ( lookahead . type === Token . Keyword ) {
switch ( lookahead . value ) {
case 'let' :
case 'const' :
case 'var' :
case 'class' :
case 'function' :
2014-01-03 15:54:38 +00:00
return delegate . createExportDeclaration ( parseSourceElement ( ) , null , null ) ;
2013-12-16 22:19:36 +00:00
}
2014-01-03 15:54:38 +00:00
}
if ( isIdentifierName ( lookahead ) ) {
previousAllowKeyword = state . allowKeyword ;
state . allowKeyword = true ;
decl = parseVariableDeclarationList ( 'let' ) ;
state . allowKeyword = previousAllowKeyword ;
return delegate . createExportDeclaration ( decl , null , null ) ;
2013-12-16 22:19:36 +00:00
}
specifiers = [ ] ;
src = null ;
if ( match ( '*' ) ) {
specifiers . push ( parseExportBatchSpecifier ( ) ) ;
} else {
expect ( '{' ) ;
do {
specifiers . push ( parseExportSpecifier ( ) ) ;
} while ( match ( ',' ) && lex ( ) ) ;
expect ( '}' ) ;
}
if ( matchContextualKeyword ( 'from' ) ) {
lex ( ) ;
src = parsePrimaryExpression ( ) ;
if ( src . type !== Syntax . Literal ) {
throwError ( { } , Messages . InvalidModuleSpecifier ) ;
}
}
consumeSemicolon ( ) ;
2014-01-03 15:54:38 +00:00
return delegate . createExportDeclaration ( null , specifiers , src ) ;
2013-12-16 22:19:36 +00:00
}
function parseImportDeclaration ( ) {
var specifiers , kind , src ;
expectKeyword ( 'import' ) ;
specifiers = [ ] ;
if ( isIdentifierName ( lookahead ) ) {
kind = 'default' ;
specifiers . push ( parseImportSpecifier ( ) ) ;
if ( ! matchContextualKeyword ( 'from' ) ) {
throwError ( { } , Messages . NoFromAfterImport ) ;
}
lex ( ) ;
} else if ( match ( '{' ) ) {
kind = 'named' ;
lex ( ) ;
do {
specifiers . push ( parseImportSpecifier ( ) ) ;
} while ( match ( ',' ) && lex ( ) ) ;
expect ( '}' ) ;
if ( ! matchContextualKeyword ( 'from' ) ) {
throwError ( { } , Messages . NoFromAfterImport ) ;
}
lex ( ) ;
}
src = parsePrimaryExpression ( ) ;
if ( src . type !== Syntax . Literal ) {
throwError ( { } , Messages . InvalidModuleSpecifier ) ;
}
consumeSemicolon ( ) ;
return delegate . createImportDeclaration ( specifiers , kind , src ) ;
}
function parseImportSpecifier ( ) {
var id , name = null ;
id = parseNonComputedProperty ( ) ;
if ( matchContextualKeyword ( 'as' ) ) {
lex ( ) ;
name = parseVariableIdentifier ( ) ;
}
return delegate . createImportSpecifier ( id , name ) ;
}
// 12.3 Empty Statement
function parseEmptyStatement ( ) {
expect ( ';' ) ;
return delegate . createEmptyStatement ( ) ;
}
// 12.4 Expression Statement
function parseExpressionStatement ( ) {
var expr = parseExpression ( ) ;
consumeSemicolon ( ) ;
return delegate . createExpressionStatement ( expr ) ;
}
// 12.5 If statement
function parseIfStatement ( ) {
var test , consequent , alternate ;
expectKeyword ( 'if' ) ;
expect ( '(' ) ;
test = parseExpression ( ) ;
expect ( ')' ) ;
consequent = parseStatement ( ) ;
if ( matchKeyword ( 'else' ) ) {
lex ( ) ;
alternate = parseStatement ( ) ;
} else {
alternate = null ;
}
return delegate . createIfStatement ( test , consequent , alternate ) ;
}
// 12.6 Iteration Statements
function parseDoWhileStatement ( ) {
var body , test , oldInIteration ;
expectKeyword ( 'do' ) ;
oldInIteration = state . inIteration ;
state . inIteration = true ;
body = parseStatement ( ) ;
state . inIteration = oldInIteration ;
expectKeyword ( 'while' ) ;
expect ( '(' ) ;
test = parseExpression ( ) ;
expect ( ')' ) ;
if ( match ( ';' ) ) {
lex ( ) ;
}
return delegate . createDoWhileStatement ( body , test ) ;
}
function parseWhileStatement ( ) {
var test , body , oldInIteration ;
expectKeyword ( 'while' ) ;
expect ( '(' ) ;
test = parseExpression ( ) ;
expect ( ')' ) ;
oldInIteration = state . inIteration ;
state . inIteration = true ;
body = parseStatement ( ) ;
state . inIteration = oldInIteration ;
return delegate . createWhileStatement ( test , body ) ;
}
function parseForVariableDeclaration ( ) {
var token = lex ( ) ,
declarations = parseVariableDeclarationList ( ) ;
return delegate . createVariableDeclaration ( declarations , token . value ) ;
}
function parseForStatement ( opts ) {
var init , test , update , left , right , body , operator , oldInIteration ;
init = test = update = null ;
expectKeyword ( 'for' ) ;
// http://wiki.ecmascript.org/doku.php?id=proposals:iterators_and_generators&s=each
if ( matchContextualKeyword ( "each" ) ) {
throwError ( { } , Messages . EachNotAllowed ) ;
}
expect ( '(' ) ;
if ( match ( ';' ) ) {
lex ( ) ;
} else {
if ( matchKeyword ( 'var' ) || matchKeyword ( 'let' ) || matchKeyword ( 'const' ) ) {
state . allowIn = false ;
init = parseForVariableDeclaration ( ) ;
state . allowIn = true ;
if ( init . declarations . length === 1 ) {
if ( matchKeyword ( 'in' ) || matchContextualKeyword ( 'of' ) ) {
operator = lookahead ;
if ( ! ( ( operator . value === 'in' || init . kind !== 'var' ) && init . declarations [ 0 ] . init ) ) {
lex ( ) ;
left = init ;
right = parseExpression ( ) ;
init = null ;
}
}
}
} else {
state . allowIn = false ;
init = parseExpression ( ) ;
state . allowIn = true ;
if ( matchContextualKeyword ( 'of' ) ) {
operator = lex ( ) ;
left = init ;
right = parseExpression ( ) ;
init = null ;
} else if ( matchKeyword ( 'in' ) ) {
// LeftHandSideExpression
if ( ! isAssignableLeftHandSide ( init ) ) {
throwError ( { } , Messages . InvalidLHSInForIn ) ;
}
operator = lex ( ) ;
left = init ;
right = parseExpression ( ) ;
init = null ;
}
}
if ( typeof left === 'undefined' ) {
expect ( ';' ) ;
}
}
if ( typeof left === 'undefined' ) {
if ( ! match ( ';' ) ) {
test = parseExpression ( ) ;
}
expect ( ';' ) ;
if ( ! match ( ')' ) ) {
update = parseExpression ( ) ;
}
}
expect ( ')' ) ;
oldInIteration = state . inIteration ;
state . inIteration = true ;
if ( ! ( opts !== undefined && opts . ignore _body ) ) {
body = parseStatement ( ) ;
}
state . inIteration = oldInIteration ;
if ( typeof left === 'undefined' ) {
return delegate . createForStatement ( init , test , update , body ) ;
}
if ( operator . value === 'in' ) {
return delegate . createForInStatement ( left , right , body ) ;
}
return delegate . createForOfStatement ( left , right , body ) ;
}
// 12.7 The continue statement
function parseContinueStatement ( ) {
var label = null , key ;
expectKeyword ( 'continue' ) ;
// Optimize the most common form: 'continue;'.
if ( source . charCodeAt ( index ) === 59 ) {
lex ( ) ;
if ( ! state . inIteration ) {
throwError ( { } , Messages . IllegalContinue ) ;
}
return delegate . createContinueStatement ( null ) ;
}
if ( peekLineTerminator ( ) ) {
if ( ! state . inIteration ) {
throwError ( { } , Messages . IllegalContinue ) ;
}
return delegate . createContinueStatement ( null ) ;
}
if ( lookahead . type === Token . Identifier ) {
label = parseVariableIdentifier ( ) ;
key = '$' + label . name ;
if ( ! Object . prototype . hasOwnProperty . call ( state . labelSet , key ) ) {
throwError ( { } , Messages . UnknownLabel , label . name ) ;
}
}
consumeSemicolon ( ) ;
if ( label === null && ! state . inIteration ) {
throwError ( { } , Messages . IllegalContinue ) ;
}
return delegate . createContinueStatement ( label ) ;
}
// 12.8 The break statement
function parseBreakStatement ( ) {
var label = null , key ;
expectKeyword ( 'break' ) ;
// Catch the very common case first: immediately a semicolon (char #59).
if ( source . charCodeAt ( index ) === 59 ) {
lex ( ) ;
if ( ! ( state . inIteration || state . inSwitch ) ) {
throwError ( { } , Messages . IllegalBreak ) ;
}
return delegate . createBreakStatement ( null ) ;
}
if ( peekLineTerminator ( ) ) {
if ( ! ( state . inIteration || state . inSwitch ) ) {
throwError ( { } , Messages . IllegalBreak ) ;
}
return delegate . createBreakStatement ( null ) ;
}
if ( lookahead . type === Token . Identifier ) {
label = parseVariableIdentifier ( ) ;
key = '$' + label . name ;
if ( ! Object . prototype . hasOwnProperty . call ( state . labelSet , key ) ) {
throwError ( { } , Messages . UnknownLabel , label . name ) ;
}
}
consumeSemicolon ( ) ;
if ( label === null && ! ( state . inIteration || state . inSwitch ) ) {
throwError ( { } , Messages . IllegalBreak ) ;
}
return delegate . createBreakStatement ( label ) ;
}
// 12.9 The return statement
function parseReturnStatement ( ) {
var argument = null ;
expectKeyword ( 'return' ) ;
if ( ! state . inFunctionBody ) {
throwErrorTolerant ( { } , Messages . IllegalReturn ) ;
}
// 'return' followed by a space and an identifier is very common.
if ( source . charCodeAt ( index ) === 32 ) {
if ( isIdentifierStart ( source . charCodeAt ( index + 1 ) ) ) {
argument = parseExpression ( ) ;
consumeSemicolon ( ) ;
return delegate . createReturnStatement ( argument ) ;
}
}
if ( peekLineTerminator ( ) ) {
return delegate . createReturnStatement ( null ) ;
}
if ( ! match ( ';' ) ) {
if ( ! match ( '}' ) && lookahead . type !== Token . EOF ) {
argument = parseExpression ( ) ;
}
}
consumeSemicolon ( ) ;
return delegate . createReturnStatement ( argument ) ;
}
// 12.10 The with statement
function parseWithStatement ( ) {
var object , body ;
if ( strict ) {
throwErrorTolerant ( { } , Messages . StrictModeWith ) ;
}
expectKeyword ( 'with' ) ;
expect ( '(' ) ;
object = parseExpression ( ) ;
expect ( ')' ) ;
body = parseStatement ( ) ;
return delegate . createWithStatement ( object , body ) ;
}
// 12.10 The swith statement
function parseSwitchCase ( ) {
var test ,
consequent = [ ] ,
sourceElement ;
if ( matchKeyword ( 'default' ) ) {
lex ( ) ;
test = null ;
} else {
expectKeyword ( 'case' ) ;
test = parseExpression ( ) ;
}
expect ( ':' ) ;
while ( index < length ) {
if ( match ( '}' ) || matchKeyword ( 'default' ) || matchKeyword ( 'case' ) ) {
break ;
}
sourceElement = parseSourceElement ( ) ;
if ( typeof sourceElement === 'undefined' ) {
break ;
}
consequent . push ( sourceElement ) ;
}
return delegate . createSwitchCase ( test , consequent ) ;
}
function parseSwitchStatement ( ) {
var discriminant , cases , clause , oldInSwitch , defaultFound ;
expectKeyword ( 'switch' ) ;
expect ( '(' ) ;
discriminant = parseExpression ( ) ;
expect ( ')' ) ;
expect ( '{' ) ;
cases = [ ] ;
if ( match ( '}' ) ) {
lex ( ) ;
return delegate . createSwitchStatement ( discriminant , cases ) ;
}
oldInSwitch = state . inSwitch ;
state . inSwitch = true ;
defaultFound = false ;
while ( index < length ) {
if ( match ( '}' ) ) {
break ;
}
clause = parseSwitchCase ( ) ;
if ( clause . test === null ) {
if ( defaultFound ) {
throwError ( { } , Messages . MultipleDefaultsInSwitch ) ;
}
defaultFound = true ;
}
cases . push ( clause ) ;
}
state . inSwitch = oldInSwitch ;
expect ( '}' ) ;
return delegate . createSwitchStatement ( discriminant , cases ) ;
}
// 12.13 The throw statement
function parseThrowStatement ( ) {
var argument ;
expectKeyword ( 'throw' ) ;
if ( peekLineTerminator ( ) ) {
throwError ( { } , Messages . NewlineAfterThrow ) ;
}
argument = parseExpression ( ) ;
consumeSemicolon ( ) ;
return delegate . createThrowStatement ( argument ) ;
}
// 12.14 The try statement
function parseCatchClause ( ) {
var param , body ;
expectKeyword ( 'catch' ) ;
expect ( '(' ) ;
if ( match ( ')' ) ) {
throwUnexpected ( lookahead ) ;
}
param = parseExpression ( ) ;
// 12.14.1
if ( strict && param . type === Syntax . Identifier && isRestrictedWord ( param . name ) ) {
throwErrorTolerant ( { } , Messages . StrictCatchVariable ) ;
}
expect ( ')' ) ;
body = parseBlock ( ) ;
return delegate . createCatchClause ( param , body ) ;
}
function parseTryStatement ( ) {
var block , handlers = [ ] , finalizer = null ;
expectKeyword ( 'try' ) ;
block = parseBlock ( ) ;
if ( matchKeyword ( 'catch' ) ) {
handlers . push ( parseCatchClause ( ) ) ;
}
if ( matchKeyword ( 'finally' ) ) {
lex ( ) ;
finalizer = parseBlock ( ) ;
}
if ( handlers . length === 0 && ! finalizer ) {
throwError ( { } , Messages . NoCatchOrFinally ) ;
}
return delegate . createTryStatement ( block , [ ] , handlers , finalizer ) ;
}
// 12.15 The debugger statement
function parseDebuggerStatement ( ) {
expectKeyword ( 'debugger' ) ;
consumeSemicolon ( ) ;
return delegate . createDebuggerStatement ( ) ;
}
// 12 Statements
function parseStatement ( ) {
var type = lookahead . type ,
expr ,
labeledBody ,
key ;
if ( type === Token . EOF ) {
throwUnexpected ( lookahead ) ;
}
if ( type === Token . Punctuator ) {
switch ( lookahead . value ) {
case ';' :
return parseEmptyStatement ( ) ;
case '{' :
return parseBlock ( ) ;
case '(' :
return parseExpressionStatement ( ) ;
default :
break ;
}
}
if ( type === Token . Keyword ) {
switch ( lookahead . value ) {
case 'break' :
return parseBreakStatement ( ) ;
case 'continue' :
return parseContinueStatement ( ) ;
case 'debugger' :
return parseDebuggerStatement ( ) ;
case 'do' :
return parseDoWhileStatement ( ) ;
case 'for' :
return parseForStatement ( ) ;
case 'function' :
return parseFunctionDeclaration ( ) ;
case 'class' :
return parseClassDeclaration ( ) ;
case 'if' :
return parseIfStatement ( ) ;
case 'return' :
return parseReturnStatement ( ) ;
case 'switch' :
return parseSwitchStatement ( ) ;
case 'throw' :
return parseThrowStatement ( ) ;
case 'try' :
return parseTryStatement ( ) ;
case 'var' :
return parseVariableStatement ( ) ;
case 'while' :
return parseWhileStatement ( ) ;
case 'with' :
return parseWithStatement ( ) ;
default :
break ;
}
}
expr = parseExpression ( ) ;
// 12.12 Labelled Statements
if ( ( expr . type === Syntax . Identifier ) && match ( ':' ) ) {
lex ( ) ;
key = '$' + expr . name ;
if ( Object . prototype . hasOwnProperty . call ( state . labelSet , key ) ) {
throwError ( { } , Messages . Redeclaration , 'Label' , expr . name ) ;
}
state . labelSet [ key ] = true ;
labeledBody = parseStatement ( ) ;
delete state . labelSet [ key ] ;
return delegate . createLabeledStatement ( expr , labeledBody ) ;
}
consumeSemicolon ( ) ;
return delegate . createExpressionStatement ( expr ) ;
}
// 13 Function Definition
function parseConciseBody ( ) {
if ( match ( '{' ) ) {
return parseFunctionSourceElements ( ) ;
}
return parseAssignmentExpression ( ) ;
}
function parseFunctionSourceElements ( ) {
var sourceElement , sourceElements = [ ] , token , directive , firstRestricted ,
oldLabelSet , oldInIteration , oldInSwitch , oldInFunctionBody , oldParenthesizedCount ;
expect ( '{' ) ;
while ( index < length ) {
if ( lookahead . type !== Token . StringLiteral ) {
break ;
}
token = lookahead ;
sourceElement = parseSourceElement ( ) ;
sourceElements . push ( sourceElement ) ;
if ( sourceElement . expression . type !== Syntax . Literal ) {
// this is not directive
break ;
}
directive = source . slice ( token . range [ 0 ] + 1 , token . range [ 1 ] - 1 ) ;
if ( directive === 'use strict' ) {
strict = true ;
if ( firstRestricted ) {
throwErrorTolerant ( firstRestricted , Messages . StrictOctalLiteral ) ;
}
} else {
if ( ! firstRestricted && token . octal ) {
firstRestricted = token ;
}
}
}
oldLabelSet = state . labelSet ;
oldInIteration = state . inIteration ;
oldInSwitch = state . inSwitch ;
oldInFunctionBody = state . inFunctionBody ;
oldParenthesizedCount = state . parenthesizedCount ;
state . labelSet = { } ;
state . inIteration = false ;
state . inSwitch = false ;
state . inFunctionBody = true ;
state . parenthesizedCount = 0 ;
while ( index < length ) {
if ( match ( '}' ) ) {
break ;
}
sourceElement = parseSourceElement ( ) ;
if ( typeof sourceElement === 'undefined' ) {
break ;
}
sourceElements . push ( sourceElement ) ;
}
expect ( '}' ) ;
state . labelSet = oldLabelSet ;
state . inIteration = oldInIteration ;
state . inSwitch = oldInSwitch ;
state . inFunctionBody = oldInFunctionBody ;
state . parenthesizedCount = oldParenthesizedCount ;
return delegate . createBlockStatement ( sourceElements ) ;
}
function validateParam ( options , param , name ) {
var key = '$' + name ;
if ( strict ) {
if ( isRestrictedWord ( name ) ) {
options . stricted = param ;
options . message = Messages . StrictParamName ;
}
if ( Object . prototype . hasOwnProperty . call ( options . paramSet , key ) ) {
options . stricted = param ;
options . message = Messages . StrictParamDupe ;
}
} else if ( ! options . firstRestricted ) {
if ( isRestrictedWord ( name ) ) {
options . firstRestricted = param ;
options . message = Messages . StrictParamName ;
} else if ( isStrictModeReservedWord ( name ) ) {
options . firstRestricted = param ;
options . message = Messages . StrictReservedWord ;
} else if ( Object . prototype . hasOwnProperty . call ( options . paramSet , key ) ) {
options . firstRestricted = param ;
options . message = Messages . StrictParamDupe ;
}
}
options . paramSet [ key ] = true ;
}
function parseParam ( options ) {
var token , rest , param , def ;
token = lookahead ;
if ( token . value === '...' ) {
token = lex ( ) ;
rest = true ;
}
if ( match ( '[' ) ) {
param = parseArrayInitialiser ( ) ;
reinterpretAsDestructuredParameter ( options , param ) ;
} else if ( match ( '{' ) ) {
if ( rest ) {
throwError ( { } , Messages . ObjectPatternAsRestParameter ) ;
}
param = parseObjectInitialiser ( ) ;
reinterpretAsDestructuredParameter ( options , param ) ;
} else {
2014-01-03 15:54:38 +00:00
// Typing rest params is awkward, so punting on that for now
2013-12-16 22:19:36 +00:00
param = rest
? parseVariableIdentifier ( )
2014-01-03 15:54:38 +00:00
: parseTypeAnnotatableIdentifier ( ) ;
2013-12-16 22:19:36 +00:00
validateParam ( options , token , token . value ) ;
if ( match ( '=' ) ) {
if ( rest ) {
throwErrorTolerant ( lookahead , Messages . DefaultRestParameter ) ;
}
lex ( ) ;
def = parseAssignmentExpression ( ) ;
++ options . defaultCount ;
}
}
if ( rest ) {
if ( ! match ( ')' ) ) {
throwError ( { } , Messages . ParameterAfterRestParameter ) ;
}
options . rest = param ;
return false ;
}
options . params . push ( param ) ;
options . defaults . push ( def ) ;
return ! match ( ')' ) ;
}
function parseParams ( firstRestricted ) {
var options ;
options = {
params : [ ] ,
defaultCount : 0 ,
defaults : [ ] ,
rest : null ,
firstRestricted : firstRestricted
} ;
expect ( '(' ) ;
if ( ! match ( ')' ) ) {
options . paramSet = { } ;
while ( index < length ) {
if ( ! parseParam ( options ) ) {
break ;
}
expect ( ',' ) ;
}
}
expect ( ')' ) ;
if ( options . defaultCount === 0 ) {
options . defaults = [ ] ;
}
if ( match ( ':' ) ) {
options . returnTypeAnnotation = parseTypeAnnotation ( ) ;
}
return options ;
}
function parseFunctionDeclaration ( ) {
var id , body , token , tmp , firstRestricted , message , previousStrict , previousYieldAllowed , generator , expression ;
expectKeyword ( 'function' ) ;
generator = false ;
if ( match ( '*' ) ) {
lex ( ) ;
generator = true ;
}
token = lookahead ;
2014-01-03 15:54:38 +00:00
id = parseVariableIdentifier ( ) ;
2013-12-16 22:19:36 +00:00
if ( strict ) {
if ( isRestrictedWord ( token . value ) ) {
throwErrorTolerant ( token , Messages . StrictFunctionName ) ;
}
} else {
if ( isRestrictedWord ( token . value ) ) {
firstRestricted = token ;
message = Messages . StrictFunctionName ;
} else if ( isStrictModeReservedWord ( token . value ) ) {
firstRestricted = token ;
message = Messages . StrictReservedWord ;
}
}
tmp = parseParams ( firstRestricted ) ;
firstRestricted = tmp . firstRestricted ;
if ( tmp . message ) {
message = tmp . message ;
}
previousStrict = strict ;
previousYieldAllowed = state . yieldAllowed ;
state . yieldAllowed = generator ;
// here we redo some work in order to set 'expression'
expression = ! match ( '{' ) ;
body = parseConciseBody ( ) ;
if ( strict && firstRestricted ) {
throwError ( firstRestricted , message ) ;
}
if ( strict && tmp . stricted ) {
throwErrorTolerant ( tmp . stricted , message ) ;
}
if ( state . yieldAllowed && ! state . yieldFound ) {
throwErrorTolerant ( { } , Messages . NoYieldInGenerator ) ;
}
strict = previousStrict ;
state . yieldAllowed = previousYieldAllowed ;
return delegate . createFunctionDeclaration ( id , tmp . params , tmp . defaults , body , tmp . rest , generator , expression ,
tmp . returnTypeAnnotation ) ;
}
function parseFunctionExpression ( ) {
var token , id = null , firstRestricted , message , tmp , body , previousStrict , previousYieldAllowed , generator , expression ;
expectKeyword ( 'function' ) ;
generator = false ;
if ( match ( '*' ) ) {
lex ( ) ;
generator = true ;
}
if ( ! match ( '(' ) ) {
token = lookahead ;
id = parseVariableIdentifier ( ) ;
if ( strict ) {
if ( isRestrictedWord ( token . value ) ) {
throwErrorTolerant ( token , Messages . StrictFunctionName ) ;
}
} else {
if ( isRestrictedWord ( token . value ) ) {
firstRestricted = token ;
message = Messages . StrictFunctionName ;
} else if ( isStrictModeReservedWord ( token . value ) ) {
firstRestricted = token ;
message = Messages . StrictReservedWord ;
}
}
}
tmp = parseParams ( firstRestricted ) ;
firstRestricted = tmp . firstRestricted ;
if ( tmp . message ) {
message = tmp . message ;
}
previousStrict = strict ;
previousYieldAllowed = state . yieldAllowed ;
state . yieldAllowed = generator ;
// here we redo some work in order to set 'expression'
expression = ! match ( '{' ) ;
body = parseConciseBody ( ) ;
if ( strict && firstRestricted ) {
throwError ( firstRestricted , message ) ;
}
if ( strict && tmp . stricted ) {
throwErrorTolerant ( tmp . stricted , message ) ;
}
if ( state . yieldAllowed && ! state . yieldFound ) {
throwErrorTolerant ( { } , Messages . NoYieldInGenerator ) ;
}
strict = previousStrict ;
state . yieldAllowed = previousYieldAllowed ;
return delegate . createFunctionExpression ( id , tmp . params , tmp . defaults , body , tmp . rest , generator , expression ,
tmp . returnTypeAnnotation ) ;
}
function parseYieldExpression ( ) {
var delegateFlag , expr , previousYieldAllowed ;
expectKeyword ( 'yield' ) ;
if ( ! state . yieldAllowed ) {
throwErrorTolerant ( { } , Messages . IllegalYield ) ;
}
delegateFlag = false ;
if ( match ( '*' ) ) {
lex ( ) ;
delegateFlag = true ;
}
// It is a Syntax Error if any AssignmentExpression Contains YieldExpression.
previousYieldAllowed = state . yieldAllowed ;
state . yieldAllowed = false ;
expr = parseAssignmentExpression ( ) ;
state . yieldAllowed = previousYieldAllowed ;
state . yieldFound = true ;
return delegate . createYieldExpression ( expr , delegateFlag ) ;
}
// 14 Classes
function parseMethodDefinition ( existingPropNames ) {
var token , key , param , propType , isValidDuplicateProp = false ;
if ( lookahead . value === 'static' ) {
propType = ClassPropertyType . static ;
lex ( ) ;
} else {
propType = ClassPropertyType . prototype ;
}
if ( match ( '*' ) ) {
lex ( ) ;
return delegate . createMethodDefinition (
propType ,
'' ,
parseObjectPropertyKey ( ) ,
parsePropertyMethodFunction ( { generator : true } )
) ;
}
token = lookahead ;
key = parseObjectPropertyKey ( ) ;
if ( token . value === 'get' && ! match ( '(' ) ) {
key = parseObjectPropertyKey ( ) ;
// It is a syntax error if any other properties have a name
// duplicating this one unless they are a setter
if ( existingPropNames [ propType ] . hasOwnProperty ( key . name ) ) {
isValidDuplicateProp =
// There isn't already a getter for this prop
existingPropNames [ propType ] [ key . name ] . get === undefined
// There isn't already a data prop by this name
&& existingPropNames [ propType ] [ key . name ] . data === undefined
// The only existing prop by this name is a setter
&& existingPropNames [ propType ] [ key . name ] . set !== undefined ;
if ( ! isValidDuplicateProp ) {
throwError ( key , Messages . IllegalDuplicateClassProperty ) ;
}
} else {
existingPropNames [ propType ] [ key . name ] = { } ;
}
existingPropNames [ propType ] [ key . name ] . get = true ;
expect ( '(' ) ;
expect ( ')' ) ;
return delegate . createMethodDefinition (
propType ,
'get' ,
key ,
parsePropertyFunction ( { generator : false } )
) ;
}
if ( token . value === 'set' && ! match ( '(' ) ) {
key = parseObjectPropertyKey ( ) ;
// It is a syntax error if any other properties have a name
// duplicating this one unless they are a getter
if ( existingPropNames [ propType ] . hasOwnProperty ( key . name ) ) {
isValidDuplicateProp =
// There isn't already a setter for this prop
existingPropNames [ propType ] [ key . name ] . set === undefined
// There isn't already a data prop by this name
&& existingPropNames [ propType ] [ key . name ] . data === undefined
// The only existing prop by this name is a getter
&& existingPropNames [ propType ] [ key . name ] . get !== undefined ;
if ( ! isValidDuplicateProp ) {
throwError ( key , Messages . IllegalDuplicateClassProperty ) ;
}
} else {
existingPropNames [ propType ] [ key . name ] = { } ;
}
existingPropNames [ propType ] [ key . name ] . set = true ;
expect ( '(' ) ;
token = lookahead ;
2014-01-03 15:54:38 +00:00
param = [ parseTypeAnnotatableIdentifier ( ) ] ;
2013-12-16 22:19:36 +00:00
expect ( ')' ) ;
return delegate . createMethodDefinition (
propType ,
'set' ,
key ,
parsePropertyFunction ( { params : param , generator : false , name : token } )
) ;
}
// It is a syntax error if any other properties have the same name as a
// non-getter, non-setter method
if ( existingPropNames [ propType ] . hasOwnProperty ( key . name ) ) {
throwError ( key , Messages . IllegalDuplicateClassProperty ) ;
} else {
existingPropNames [ propType ] [ key . name ] = { } ;
}
existingPropNames [ propType ] [ key . name ] . data = true ;
return delegate . createMethodDefinition (
propType ,
'' ,
key ,
parsePropertyMethodFunction ( { generator : false } )
) ;
}
function parseClassElement ( existingProps ) {
if ( match ( ';' ) ) {
lex ( ) ;
return ;
}
return parseMethodDefinition ( existingProps ) ;
}
function parseClassBody ( ) {
var classElement , classElements = [ ] , existingProps = { } ;
existingProps [ ClassPropertyType . static ] = { } ;
existingProps [ ClassPropertyType . prototype ] = { } ;
expect ( '{' ) ;
while ( index < length ) {
if ( match ( '}' ) ) {
break ;
}
classElement = parseClassElement ( existingProps ) ;
if ( typeof classElement !== 'undefined' ) {
classElements . push ( classElement ) ;
}
}
expect ( '}' ) ;
return delegate . createClassBody ( classElements ) ;
}
function parseClassExpression ( ) {
var id , previousYieldAllowed , superClass = null ;
expectKeyword ( 'class' ) ;
if ( ! matchKeyword ( 'extends' ) && ! match ( '{' ) ) {
id = parseVariableIdentifier ( ) ;
}
if ( matchKeyword ( 'extends' ) ) {
expectKeyword ( 'extends' ) ;
previousYieldAllowed = state . yieldAllowed ;
state . yieldAllowed = false ;
superClass = parseAssignmentExpression ( ) ;
state . yieldAllowed = previousYieldAllowed ;
}
return delegate . createClassExpression ( id , superClass , parseClassBody ( ) ) ;
}
function parseClassDeclaration ( ) {
var id , previousYieldAllowed , superClass = null ;
expectKeyword ( 'class' ) ;
2014-01-03 15:54:38 +00:00
id = parseVariableIdentifier ( ) ;
2013-12-16 22:19:36 +00:00
if ( matchKeyword ( 'extends' ) ) {
expectKeyword ( 'extends' ) ;
previousYieldAllowed = state . yieldAllowed ;
state . yieldAllowed = false ;
superClass = parseAssignmentExpression ( ) ;
state . yieldAllowed = previousYieldAllowed ;
}
return delegate . createClassDeclaration ( id , superClass , parseClassBody ( ) ) ;
}
// 15 Program
function matchModuleDeclaration ( ) {
var id ;
if ( matchContextualKeyword ( 'module' ) ) {
id = lookahead2 ( ) ;
return id . type === Token . StringLiteral || id . type === Token . Identifier ;
}
return false ;
}
function parseSourceElement ( ) {
if ( lookahead . type === Token . Keyword ) {
switch ( lookahead . value ) {
case 'const' :
case 'let' :
return parseConstLetDeclaration ( lookahead . value ) ;
case 'function' :
return parseFunctionDeclaration ( ) ;
case 'export' :
return parseExportDeclaration ( ) ;
case 'import' :
return parseImportDeclaration ( ) ;
default :
return parseStatement ( ) ;
}
}
if ( matchModuleDeclaration ( ) ) {
throwError ( { } , Messages . NestedModule ) ;
}
if ( lookahead . type !== Token . EOF ) {
return parseStatement ( ) ;
}
}
function parseProgramElement ( ) {
if ( lookahead . type === Token . Keyword ) {
switch ( lookahead . value ) {
case 'export' :
return parseExportDeclaration ( ) ;
case 'import' :
return parseImportDeclaration ( ) ;
}
}
if ( matchModuleDeclaration ( ) ) {
return parseModuleDeclaration ( ) ;
}
return parseSourceElement ( ) ;
}
function parseProgramElements ( ) {
var sourceElement , sourceElements = [ ] , token , directive , firstRestricted ;
while ( index < length ) {
token = lookahead ;
if ( token . type !== Token . StringLiteral ) {
break ;
}
sourceElement = parseProgramElement ( ) ;
sourceElements . push ( sourceElement ) ;
if ( sourceElement . expression . type !== Syntax . Literal ) {
// this is not directive
break ;
}
directive = source . slice ( token . range [ 0 ] + 1 , token . range [ 1 ] - 1 ) ;
if ( directive === 'use strict' ) {
strict = true ;
if ( firstRestricted ) {
throwErrorTolerant ( firstRestricted , Messages . StrictOctalLiteral ) ;
}
} else {
if ( ! firstRestricted && token . octal ) {
firstRestricted = token ;
}
}
}
while ( index < length ) {
sourceElement = parseProgramElement ( ) ;
if ( typeof sourceElement === 'undefined' ) {
break ;
}
sourceElements . push ( sourceElement ) ;
}
return sourceElements ;
}
function parseModuleElement ( ) {
return parseSourceElement ( ) ;
}
function parseModuleElements ( ) {
var list = [ ] ,
statement ;
while ( index < length ) {
if ( match ( '}' ) ) {
break ;
}
statement = parseModuleElement ( ) ;
if ( typeof statement === 'undefined' ) {
break ;
}
list . push ( statement ) ;
}
return list ;
}
function parseModuleBlock ( ) {
var block ;
expect ( '{' ) ;
block = parseModuleElements ( ) ;
expect ( '}' ) ;
return delegate . createBlockStatement ( block ) ;
}
function parseProgram ( ) {
var body ;
strict = false ;
peek ( ) ;
body = parseProgramElements ( ) ;
return delegate . createProgram ( body ) ;
}
// The following functions are needed only when the option to preserve
// the comments is active.
function addComment ( type , value , start , end , loc ) {
assert ( typeof start === 'number' , 'Comment must have valid position' ) ;
// Because the way the actual token is scanned, often the comments
// (if any) are skipped twice during the lexical analysis.
// Thus, we need to skip adding a comment if the comment array already
// handled it.
if ( extra . comments . length > 0 ) {
if ( extra . comments [ extra . comments . length - 1 ] . range [ 1 ] > start ) {
return ;
}
}
extra . comments . push ( {
type : type ,
value : value ,
range : [ start , end ] ,
loc : loc
} ) ;
}
function scanComment ( ) {
var comment , ch , loc , start , blockComment , lineComment ;
comment = '' ;
blockComment = false ;
lineComment = false ;
while ( index < length ) {
ch = source [ index ] ;
if ( lineComment ) {
ch = source [ index ++ ] ;
if ( isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
loc . end = {
line : lineNumber ,
column : index - lineStart - 1
} ;
lineComment = false ;
addComment ( 'Line' , comment , start , index - 1 , loc ) ;
if ( ch === '\r' && source [ index ] === '\n' ) {
++ index ;
}
++ lineNumber ;
lineStart = index ;
comment = '' ;
} else if ( index >= length ) {
lineComment = false ;
comment += ch ;
loc . end = {
line : lineNumber ,
column : length - lineStart
} ;
addComment ( 'Line' , comment , start , length , loc ) ;
} else {
comment += ch ;
}
} else if ( blockComment ) {
if ( isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
if ( ch === '\r' && source [ index + 1 ] === '\n' ) {
++ index ;
comment += '\r\n' ;
} else {
comment += ch ;
}
++ lineNumber ;
++ index ;
lineStart = index ;
if ( index >= length ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
} else {
ch = source [ index ++ ] ;
if ( index >= length ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
comment += ch ;
if ( ch === '*' ) {
ch = source [ index ] ;
if ( ch === '/' ) {
comment = comment . substr ( 0 , comment . length - 1 ) ;
blockComment = false ;
++ index ;
loc . end = {
line : lineNumber ,
column : index - lineStart
} ;
addComment ( 'Block' , comment , start , index , loc ) ;
comment = '' ;
}
}
}
} else if ( ch === '/' ) {
ch = source [ index + 1 ] ;
if ( ch === '/' ) {
loc = {
start : {
line : lineNumber ,
column : index - lineStart
}
} ;
start = index ;
index += 2 ;
lineComment = true ;
if ( index >= length ) {
loc . end = {
line : lineNumber ,
column : index - lineStart
} ;
lineComment = false ;
addComment ( 'Line' , comment , start , index , loc ) ;
}
} else if ( ch === '*' ) {
start = index ;
index += 2 ;
blockComment = true ;
loc = {
start : {
line : lineNumber ,
column : index - lineStart - 2
}
} ;
if ( index >= length ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
} else {
break ;
}
} else if ( isWhiteSpace ( ch . charCodeAt ( 0 ) ) ) {
++ index ;
} else if ( isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
++ index ;
if ( ch === '\r' && source [ index ] === '\n' ) {
++ index ;
}
++ lineNumber ;
lineStart = index ;
} else {
break ;
}
}
}
function filterCommentLocation ( ) {
var i , entry , comment , comments = [ ] ;
for ( i = 0 ; i < extra . comments . length ; ++ i ) {
entry = extra . comments [ i ] ;
comment = {
type : entry . type ,
value : entry . value
} ;
if ( extra . range ) {
comment . range = entry . range ;
}
if ( extra . loc ) {
comment . loc = entry . loc ;
}
comments . push ( comment ) ;
}
extra . comments = comments ;
}
// 16 XJS
XHTMLEntities = {
quot : '\u0022' ,
amp : '&' ,
apos : "\u0027" ,
lt : "<" ,
gt : ">" ,
nbsp : "\u00A0" ,
iexcl : "\u00A1" ,
cent : "\u00A2" ,
pound : "\u00A3" ,
curren : "\u00A4" ,
yen : "\u00A5" ,
brvbar : "\u00A6" ,
sect : "\u00A7" ,
uml : "\u00A8" ,
copy : "\u00A9" ,
ordf : "\u00AA" ,
laquo : "\u00AB" ,
not : "\u00AC" ,
shy : "\u00AD" ,
reg : "\u00AE" ,
macr : "\u00AF" ,
deg : "\u00B0" ,
plusmn : "\u00B1" ,
sup2 : "\u00B2" ,
sup3 : "\u00B3" ,
acute : "\u00B4" ,
micro : "\u00B5" ,
para : "\u00B6" ,
middot : "\u00B7" ,
cedil : "\u00B8" ,
sup1 : "\u00B9" ,
ordm : "\u00BA" ,
raquo : "\u00BB" ,
frac14 : "\u00BC" ,
frac12 : "\u00BD" ,
frac34 : "\u00BE" ,
iquest : "\u00BF" ,
Agrave : "\u00C0" ,
Aacute : "\u00C1" ,
Acirc : "\u00C2" ,
Atilde : "\u00C3" ,
Auml : "\u00C4" ,
Aring : "\u00C5" ,
AElig : "\u00C6" ,
Ccedil : "\u00C7" ,
Egrave : "\u00C8" ,
Eacute : "\u00C9" ,
Ecirc : "\u00CA" ,
Euml : "\u00CB" ,
Igrave : "\u00CC" ,
Iacute : "\u00CD" ,
Icirc : "\u00CE" ,
Iuml : "\u00CF" ,
ETH : "\u00D0" ,
Ntilde : "\u00D1" ,
Ograve : "\u00D2" ,
Oacute : "\u00D3" ,
Ocirc : "\u00D4" ,
Otilde : "\u00D5" ,
Ouml : "\u00D6" ,
times : "\u00D7" ,
Oslash : "\u00D8" ,
Ugrave : "\u00D9" ,
Uacute : "\u00DA" ,
Ucirc : "\u00DB" ,
Uuml : "\u00DC" ,
Yacute : "\u00DD" ,
THORN : "\u00DE" ,
szlig : "\u00DF" ,
agrave : "\u00E0" ,
aacute : "\u00E1" ,
acirc : "\u00E2" ,
atilde : "\u00E3" ,
auml : "\u00E4" ,
aring : "\u00E5" ,
aelig : "\u00E6" ,
ccedil : "\u00E7" ,
egrave : "\u00E8" ,
eacute : "\u00E9" ,
ecirc : "\u00EA" ,
euml : "\u00EB" ,
igrave : "\u00EC" ,
iacute : "\u00ED" ,
icirc : "\u00EE" ,
iuml : "\u00EF" ,
eth : "\u00F0" ,
ntilde : "\u00F1" ,
ograve : "\u00F2" ,
oacute : "\u00F3" ,
ocirc : "\u00F4" ,
otilde : "\u00F5" ,
ouml : "\u00F6" ,
divide : "\u00F7" ,
oslash : "\u00F8" ,
ugrave : "\u00F9" ,
uacute : "\u00FA" ,
ucirc : "\u00FB" ,
uuml : "\u00FC" ,
yacute : "\u00FD" ,
thorn : "\u00FE" ,
yuml : "\u00FF" ,
OElig : "\u0152" ,
oelig : "\u0153" ,
Scaron : "\u0160" ,
scaron : "\u0161" ,
Yuml : "\u0178" ,
fnof : "\u0192" ,
circ : "\u02C6" ,
tilde : "\u02DC" ,
Alpha : "\u0391" ,
Beta : "\u0392" ,
Gamma : "\u0393" ,
Delta : "\u0394" ,
Epsilon : "\u0395" ,
Zeta : "\u0396" ,
Eta : "\u0397" ,
Theta : "\u0398" ,
Iota : "\u0399" ,
Kappa : "\u039A" ,
Lambda : "\u039B" ,
Mu : "\u039C" ,
Nu : "\u039D" ,
Xi : "\u039E" ,
Omicron : "\u039F" ,
Pi : "\u03A0" ,
Rho : "\u03A1" ,
Sigma : "\u03A3" ,
Tau : "\u03A4" ,
Upsilon : "\u03A5" ,
Phi : "\u03A6" ,
Chi : "\u03A7" ,
Psi : "\u03A8" ,
Omega : "\u03A9" ,
alpha : "\u03B1" ,
beta : "\u03B2" ,
gamma : "\u03B3" ,
delta : "\u03B4" ,
epsilon : "\u03B5" ,
zeta : "\u03B6" ,
eta : "\u03B7" ,
theta : "\u03B8" ,
iota : "\u03B9" ,
kappa : "\u03BA" ,
lambda : "\u03BB" ,
mu : "\u03BC" ,
nu : "\u03BD" ,
xi : "\u03BE" ,
omicron : "\u03BF" ,
pi : "\u03C0" ,
rho : "\u03C1" ,
sigmaf : "\u03C2" ,
sigma : "\u03C3" ,
tau : "\u03C4" ,
upsilon : "\u03C5" ,
phi : "\u03C6" ,
chi : "\u03C7" ,
psi : "\u03C8" ,
omega : "\u03C9" ,
thetasym : "\u03D1" ,
upsih : "\u03D2" ,
piv : "\u03D6" ,
ensp : "\u2002" ,
emsp : "\u2003" ,
thinsp : "\u2009" ,
zwnj : "\u200C" ,
zwj : "\u200D" ,
lrm : "\u200E" ,
rlm : "\u200F" ,
ndash : "\u2013" ,
mdash : "\u2014" ,
lsquo : "\u2018" ,
rsquo : "\u2019" ,
sbquo : "\u201A" ,
ldquo : "\u201C" ,
rdquo : "\u201D" ,
bdquo : "\u201E" ,
dagger : "\u2020" ,
Dagger : "\u2021" ,
bull : "\u2022" ,
hellip : "\u2026" ,
permil : "\u2030" ,
prime : "\u2032" ,
Prime : "\u2033" ,
lsaquo : "\u2039" ,
rsaquo : "\u203A" ,
oline : "\u203E" ,
frasl : "\u2044" ,
euro : "\u20AC" ,
image : "\u2111" ,
weierp : "\u2118" ,
real : "\u211C" ,
trade : "\u2122" ,
alefsym : "\u2135" ,
larr : "\u2190" ,
uarr : "\u2191" ,
rarr : "\u2192" ,
darr : "\u2193" ,
harr : "\u2194" ,
crarr : "\u21B5" ,
lArr : "\u21D0" ,
uArr : "\u21D1" ,
rArr : "\u21D2" ,
dArr : "\u21D3" ,
hArr : "\u21D4" ,
forall : "\u2200" ,
part : "\u2202" ,
exist : "\u2203" ,
empty : "\u2205" ,
nabla : "\u2207" ,
isin : "\u2208" ,
notin : "\u2209" ,
ni : "\u220B" ,
prod : "\u220F" ,
sum : "\u2211" ,
minus : "\u2212" ,
lowast : "\u2217" ,
radic : "\u221A" ,
prop : "\u221D" ,
infin : "\u221E" ,
ang : "\u2220" ,
and : "\u2227" ,
or : "\u2228" ,
cap : "\u2229" ,
cup : "\u222A" ,
"int" : "\u222B" ,
there4 : "\u2234" ,
sim : "\u223C" ,
cong : "\u2245" ,
asymp : "\u2248" ,
ne : "\u2260" ,
equiv : "\u2261" ,
le : "\u2264" ,
ge : "\u2265" ,
sub : "\u2282" ,
sup : "\u2283" ,
nsub : "\u2284" ,
sube : "\u2286" ,
supe : "\u2287" ,
oplus : "\u2295" ,
otimes : "\u2297" ,
perp : "\u22A5" ,
sdot : "\u22C5" ,
lceil : "\u2308" ,
rceil : "\u2309" ,
lfloor : "\u230A" ,
rfloor : "\u230B" ,
lang : "\u2329" ,
rang : "\u232A" ,
loz : "\u25CA" ,
spades : "\u2660" ,
clubs : "\u2663" ,
hearts : "\u2665" ,
diams : "\u2666"
} ;
function isXJSIdentifierStart ( ch ) {
// exclude backslash (\)
return ( ch !== 92 ) && isIdentifierStart ( ch ) ;
}
function isXJSIdentifierPart ( ch ) {
// exclude backslash (\) and add hyphen (-)
return ( ch !== 92 ) && ( ch === 45 || isIdentifierPart ( ch ) ) ;
}
function scanXJSIdentifier ( ) {
var ch , start , id = '' , namespace ;
start = index ;
while ( index < length ) {
ch = source . charCodeAt ( index ) ;
if ( ! isXJSIdentifierPart ( ch ) ) {
break ;
}
id += source [ index ++ ] ;
}
if ( ch === 58 ) { // :
++ index ;
namespace = id ;
id = '' ;
while ( index < length ) {
ch = source . charCodeAt ( index ) ;
if ( ! isXJSIdentifierPart ( ch ) ) {
break ;
}
id += source [ index ++ ] ;
}
}
if ( ! id ) {
throwError ( { } , Messages . InvalidXJSTagName ) ;
}
return {
type : Token . XJSIdentifier ,
value : id ,
namespace : namespace ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
function scanXJSEntity ( ) {
var ch , str = '' , count = 0 , entity ;
ch = source [ index ] ;
assert ( ch === '&' , 'Entity must start with an ampersand' ) ;
index ++ ;
while ( index < length && count ++ < 10 ) {
ch = source [ index ++ ] ;
if ( ch === ';' ) {
break ;
}
str += ch ;
}
if ( str [ 0 ] === '#' && str [ 1 ] === 'x' ) {
entity = String . fromCharCode ( parseInt ( str . substr ( 2 ) , 16 ) ) ;
} else if ( str [ 0 ] === '#' ) {
entity = String . fromCharCode ( parseInt ( str . substr ( 1 ) , 10 ) ) ;
} else {
entity = XHTMLEntities [ str ] ;
}
return entity ;
}
function scanXJSText ( stopChars ) {
var ch , str = '' , start ;
start = index ;
while ( index < length ) {
ch = source [ index ] ;
if ( stopChars . indexOf ( ch ) !== - 1 ) {
break ;
}
if ( ch === '&' ) {
str += scanXJSEntity ( ) ;
} else {
ch = source [ index ++ ] ;
if ( isLineTerminator ( ch . charCodeAt ( 0 ) ) ) {
++ lineNumber ;
lineStart = index ;
}
str += ch ;
}
}
return {
type : Token . XJSText ,
value : str ,
lineNumber : lineNumber ,
lineStart : lineStart ,
range : [ start , index ]
} ;
}
function scanXJSStringLiteral ( ) {
var innerToken , quote , start ;
quote = source [ index ] ;
assert ( ( quote === '\'' || quote === '"' ) ,
'String literal must starts with a quote' ) ;
start = index ;
++ index ;
innerToken = scanXJSText ( [ quote ] ) ;
if ( quote !== source [ index ] ) {
throwError ( { } , Messages . UnexpectedToken , 'ILLEGAL' ) ;
}
++ index ;
innerToken . range = [ start , index ] ;
return innerToken ;
}
/ * *
* Between XJS opening and closing tags ( e . g . < foo > HERE < / f o o > ) , a n y t h i n g t h a t
* is not another XJS tag and is not an expression wrapped by { } is text .
* /
function advanceXJSChild ( ) {
var ch = source . charCodeAt ( index ) ;
// { (123) and < (60)
if ( ch !== 123 && ch !== 60 ) {
return scanXJSText ( [ '<' , '{' ] ) ;
}
return scanPunctuator ( ) ;
}
function parseXJSIdentifier ( ) {
var token ;
if ( lookahead . type !== Token . XJSIdentifier ) {
throwUnexpected ( lookahead ) ;
}
token = lex ( ) ;
return delegate . createXJSIdentifier ( token . value , token . namespace ) ;
}
function parseXJSAttributeValue ( ) {
var value ;
if ( match ( '{' ) ) {
value = parseXJSExpressionContainer ( ) ;
if ( value . expression . type === Syntax . XJSEmptyExpression ) {
throwError (
value ,
'XJS attributes must only be assigned a non-empty ' +
'expression'
) ;
}
} else if ( lookahead . type === Token . XJSText ) {
value = delegate . createLiteral ( lex ( ) ) ;
} else {
throwError ( { } , Messages . InvalidXJSAttributeValue ) ;
}
return value ;
}
function parseXJSEmptyExpression ( ) {
while ( source . charAt ( index ) !== '}' ) {
index ++ ;
}
return delegate . createXJSEmptyExpression ( ) ;
}
function parseXJSExpressionContainer ( ) {
var expression , origInXJSChild , origInXJSTag ;
origInXJSChild = state . inXJSChild ;
origInXJSTag = state . inXJSTag ;
state . inXJSChild = false ;
state . inXJSTag = false ;
expect ( '{' ) ;
if ( match ( '}' ) ) {
expression = parseXJSEmptyExpression ( ) ;
} else {
expression = parseExpression ( ) ;
}
state . inXJSChild = origInXJSChild ;
state . inXJSTag = origInXJSTag ;
expect ( '}' ) ;
return delegate . createXJSExpressionContainer ( expression ) ;
}
function parseXJSAttribute ( ) {
var token , name , value ;
name = parseXJSIdentifier ( ) ;
// HTML empty attribute
if ( match ( '=' ) ) {
lex ( ) ;
return delegate . createXJSAttribute ( name , parseXJSAttributeValue ( ) ) ;
}
return delegate . createXJSAttribute ( name ) ;
}
function parseXJSChild ( ) {
var token ;
if ( match ( '{' ) ) {
token = parseXJSExpressionContainer ( ) ;
} else if ( lookahead . type === Token . XJSText ) {
token = delegate . createLiteral ( lex ( ) ) ;
} else {
state . inXJSChild = false ;
token = parseXJSElement ( ) ;
state . inXJSChild = true ;
}
return token ;
}
function parseXJSClosingElement ( ) {
var name , origInXJSTag ;
origInXJSTag = state . inXJSTag ;
state . inXJSTag = true ;
state . inXJSChild = false ;
expect ( '<' ) ;
expect ( '/' ) ;
name = parseXJSIdentifier ( ) ;
state . inXJSTag = origInXJSTag ;
expect ( '>' ) ;
return delegate . createXJSClosingElement ( name ) ;
}
function parseXJSOpeningElement ( ) {
var name , attribute , attributes = [ ] , selfClosing = false , origInXJSTag ;
origInXJSTag = state . inXJSTag ;
state . inXJSTag = true ;
expect ( '<' ) ;
name = parseXJSIdentifier ( ) ;
while ( index < length &&
lookahead . value !== '/' &&
lookahead . value !== '>' ) {
attributes . push ( parseXJSAttribute ( ) ) ;
}
state . inXJSTag = origInXJSTag ;
if ( lookahead . value === '/' ) {
expect ( '/' ) ;
expect ( '>' ) ;
selfClosing = true ;
} else {
state . inXJSChild = true ;
expect ( '>' ) ;
}
return delegate . createXJSOpeningElement ( name , attributes , selfClosing ) ;
}
function parseXJSElement ( ) {
var openingElement , closingElement , children = [ ] , origInXJSChild ;
openingElement = parseXJSOpeningElement ( ) ;
if ( ! openingElement . selfClosing ) {
origInXJSChild = state . inXJSChild ;
while ( index < length ) {
state . inXJSChild = false ; // </ should not be considered in the child
if ( lookahead . value === '<' && lookahead2 ( ) . value === '/' ) {
break ;
}
state . inXJSChild = true ;
peek ( ) ; // reset lookahead token
children . push ( parseXJSChild ( ) ) ;
}
state . inXJSChild = origInXJSChild ;
closingElement = parseXJSClosingElement ( ) ;
if ( closingElement . name . namespace !== openingElement . name . namespace || closingElement . name . name !== openingElement . name . name ) {
throwError ( { } , Messages . ExpectedXJSClosingTag , openingElement . name . namespace ? openingElement . name . namespace + ':' + openingElement . name . name : openingElement . name . name ) ;
}
}
return delegate . createXJSElement ( openingElement , closingElement , children ) ;
}
function collectToken ( ) {
var start , loc , token , range , value ;
skipComment ( ) ;
start = index ;
loc = {
start : {
line : lineNumber ,
column : index - lineStart
}
} ;
token = extra . advance ( ) ;
loc . end = {
line : lineNumber ,
column : index - lineStart
} ;
if ( token . type !== Token . EOF ) {
range = [ token . range [ 0 ] , token . range [ 1 ] ] ;
value = source . slice ( token . range [ 0 ] , token . range [ 1 ] ) ;
extra . tokens . push ( {
type : TokenName [ token . type ] ,
value : value ,
range : range ,
loc : loc
} ) ;
}
return token ;
}
function collectRegex ( ) {
var pos , loc , regex , token ;
skipComment ( ) ;
pos = index ;
loc = {
start : {
line : lineNumber ,
column : index - lineStart
}
} ;
regex = extra . scanRegExp ( ) ;
loc . end = {
line : lineNumber ,
column : index - lineStart
} ;
if ( ! extra . tokenize ) {
// Pop the previous token, which is likely '/' or '/='
if ( extra . tokens . length > 0 ) {
token = extra . tokens [ extra . tokens . length - 1 ] ;
if ( token . range [ 0 ] === pos && token . type === 'Punctuator' ) {
if ( token . value === '/' || token . value === '/=' ) {
extra . tokens . pop ( ) ;
}
}
}
extra . tokens . push ( {
type : 'RegularExpression' ,
value : regex . literal ,
range : [ pos , index ] ,
loc : loc
} ) ;
}
return regex ;
}
function filterTokenLocation ( ) {
var i , entry , token , tokens = [ ] ;
for ( i = 0 ; i < extra . tokens . length ; ++ i ) {
entry = extra . tokens [ i ] ;
token = {
type : entry . type ,
value : entry . value
} ;
if ( extra . range ) {
token . range = entry . range ;
}
if ( extra . loc ) {
token . loc = entry . loc ;
}
tokens . push ( token ) ;
}
extra . tokens = tokens ;
}
function LocationMarker ( ) {
this . range = [ index , index ] ;
this . loc = {
start : {
line : lineNumber ,
column : index - lineStart
} ,
end : {
line : lineNumber ,
column : index - lineStart
}
} ;
}
LocationMarker . prototype = {
constructor : LocationMarker ,
end : function ( ) {
this . range [ 1 ] = index ;
this . loc . end . line = lineNumber ;
this . loc . end . column = index - lineStart ;
} ,
applyGroup : function ( node ) {
if ( extra . range ) {
node . groupRange = [ this . range [ 0 ] , this . range [ 1 ] ] ;
}
if ( extra . loc ) {
node . groupLoc = {
start : {
line : this . loc . start . line ,
column : this . loc . start . column
} ,
end : {
line : this . loc . end . line ,
column : this . loc . end . column
}
} ;
node = delegate . postProcess ( node ) ;
}
} ,
apply : function ( node ) {
var nodeType = typeof node ;
assert ( nodeType === "object" ,
"Applying location marker to an unexpected node type: " +
nodeType ) ;
if ( extra . range ) {
node . range = [ this . range [ 0 ] , this . range [ 1 ] ] ;
}
if ( extra . loc ) {
node . loc = {
start : {
line : this . loc . start . line ,
column : this . loc . start . column
} ,
end : {
line : this . loc . end . line ,
column : this . loc . end . column
}
} ;
node = delegate . postProcess ( node ) ;
}
}
} ;
function createLocationMarker ( ) {
return new LocationMarker ( ) ;
}
function trackGroupExpression ( ) {
var marker , expr ;
skipComment ( ) ;
marker = createLocationMarker ( ) ;
expect ( '(' ) ;
++ state . parenthesizedCount ;
state . allowArrowFunction = ! state . allowArrowFunction ;
expr = parseExpression ( ) ;
state . allowArrowFunction = false ;
if ( expr . type === 'ArrowFunctionExpression' ) {
marker . end ( ) ;
marker . apply ( expr ) ;
} else {
expect ( ')' ) ;
marker . end ( ) ;
marker . applyGroup ( expr ) ;
}
return expr ;
}
function trackLeftHandSideExpression ( ) {
var marker , expr ;
skipComment ( ) ;
marker = createLocationMarker ( ) ;
expr = matchKeyword ( 'new' ) ? parseNewExpression ( ) : parsePrimaryExpression ( ) ;
while ( match ( '.' ) || match ( '[' ) || lookahead . type === Token . Template ) {
if ( match ( '[' ) ) {
expr = delegate . createMemberExpression ( '[' , expr , parseComputedMember ( ) ) ;
marker . end ( ) ;
marker . apply ( expr ) ;
} else if ( match ( '.' ) ) {
expr = delegate . createMemberExpression ( '.' , expr , parseNonComputedMember ( ) ) ;
marker . end ( ) ;
marker . apply ( expr ) ;
} else {
expr = delegate . createTaggedTemplateExpression ( expr , parseTemplateLiteral ( ) ) ;
marker . end ( ) ;
marker . apply ( expr ) ;
}
}
return expr ;
}
function trackLeftHandSideExpressionAllowCall ( ) {
var marker , expr , args ;
skipComment ( ) ;
marker = createLocationMarker ( ) ;
expr = matchKeyword ( 'new' ) ? parseNewExpression ( ) : parsePrimaryExpression ( ) ;
while ( match ( '.' ) || match ( '[' ) || match ( '(' ) || lookahead . type === Token . Template ) {
if ( match ( '(' ) ) {
args = parseArguments ( ) ;
expr = delegate . createCallExpression ( expr , args ) ;
marker . end ( ) ;
marker . apply ( expr ) ;
} else if ( match ( '[' ) ) {
expr = delegate . createMemberExpression ( '[' , expr , parseComputedMember ( ) ) ;
marker . end ( ) ;
marker . apply ( expr ) ;
} else if ( match ( '.' ) ) {
expr = delegate . createMemberExpression ( '.' , expr , parseNonComputedMember ( ) ) ;
marker . end ( ) ;
marker . apply ( expr ) ;
} else {
expr = delegate . createTaggedTemplateExpression ( expr , parseTemplateLiteral ( ) ) ;
marker . end ( ) ;
marker . apply ( expr ) ;
}
}
return expr ;
}
function filterGroup ( node ) {
var n , i , entry ;
n = ( Object . prototype . toString . apply ( node ) === '[object Array]' ) ? [ ] : { } ;
for ( i in node ) {
if ( node . hasOwnProperty ( i ) && i !== 'groupRange' && i !== 'groupLoc' ) {
entry = node [ i ] ;
if ( entry === null || typeof entry !== 'object' || entry instanceof RegExp ) {
n [ i ] = entry ;
} else {
n [ i ] = filterGroup ( entry ) ;
}
}
}
return n ;
}
function wrapTrackingFunction ( range , loc , preserveWhitespace ) {
return function ( parseFunction ) {
function isBinary ( node ) {
return node . type === Syntax . LogicalExpression ||
node . type === Syntax . BinaryExpression ;
}
function visit ( node ) {
var start , end ;
if ( isBinary ( node . left ) ) {
visit ( node . left ) ;
}
if ( isBinary ( node . right ) ) {
visit ( node . right ) ;
}
if ( range ) {
if ( node . left . groupRange || node . right . groupRange ) {
start = node . left . groupRange ? node . left . groupRange [ 0 ] : node . left . range [ 0 ] ;
end = node . right . groupRange ? node . right . groupRange [ 1 ] : node . right . range [ 1 ] ;
node . range = [ start , end ] ;
} else if ( typeof node . range === 'undefined' ) {
start = node . left . range [ 0 ] ;
end = node . right . range [ 1 ] ;
node . range = [ start , end ] ;
}
}
if ( loc ) {
if ( node . left . groupLoc || node . right . groupLoc ) {
start = node . left . groupLoc ? node . left . groupLoc . start : node . left . loc . start ;
end = node . right . groupLoc ? node . right . groupLoc . end : node . right . loc . end ;
node . loc = {
start : start ,
end : end
} ;
node = delegate . postProcess ( node ) ;
} else if ( typeof node . loc === 'undefined' ) {
node . loc = {
start : node . left . loc . start ,
end : node . right . loc . end
} ;
node = delegate . postProcess ( node ) ;
}
}
}
return function ( ) {
var marker , node ;
if ( ! preserveWhitespace ) {
skipComment ( ) ;
}
marker = createLocationMarker ( ) ;
node = parseFunction . apply ( null , arguments ) ;
marker . end ( ) ;
if ( range && typeof node . range === 'undefined' ) {
marker . apply ( node ) ;
}
if ( loc && typeof node . loc === 'undefined' ) {
marker . apply ( node ) ;
}
if ( isBinary ( node ) ) {
visit ( node ) ;
}
return node ;
} ;
} ;
}
function patch ( ) {
var wrapTracking , wrapTrackingPreserveWhitespace ;
if ( extra . comments ) {
extra . skipComment = skipComment ;
skipComment = scanComment ;
}
if ( extra . range || extra . loc ) {
extra . parseGroupExpression = parseGroupExpression ;
extra . parseLeftHandSideExpression = parseLeftHandSideExpression ;
extra . parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall ;
parseGroupExpression = trackGroupExpression ;
parseLeftHandSideExpression = trackLeftHandSideExpression ;
parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall ;
wrapTracking = wrapTrackingFunction ( extra . range , extra . loc ) ;
wrapTrackingPreserveWhitespace =
wrapTrackingFunction ( extra . range , extra . loc , true ) ;
extra . parseAssignmentExpression = parseAssignmentExpression ;
extra . parseBinaryExpression = parseBinaryExpression ;
extra . parseBlock = parseBlock ;
extra . parseFunctionSourceElements = parseFunctionSourceElements ;
extra . parseCatchClause = parseCatchClause ;
extra . parseComputedMember = parseComputedMember ;
extra . parseConditionalExpression = parseConditionalExpression ;
extra . parseConstLetDeclaration = parseConstLetDeclaration ;
extra . parseExportBatchSpecifier = parseExportBatchSpecifier ;
extra . parseExportDeclaration = parseExportDeclaration ;
extra . parseExportSpecifier = parseExportSpecifier ;
extra . parseExpression = parseExpression ;
extra . parseForVariableDeclaration = parseForVariableDeclaration ;
extra . parseFunctionDeclaration = parseFunctionDeclaration ;
extra . parseFunctionExpression = parseFunctionExpression ;
extra . parseParams = parseParams ;
extra . parseImportDeclaration = parseImportDeclaration ;
extra . parseImportSpecifier = parseImportSpecifier ;
extra . parseModuleDeclaration = parseModuleDeclaration ;
extra . parseModuleBlock = parseModuleBlock ;
extra . parseNewExpression = parseNewExpression ;
extra . parseNonComputedProperty = parseNonComputedProperty ;
extra . parseObjectProperty = parseObjectProperty ;
extra . parseObjectPropertyKey = parseObjectPropertyKey ;
extra . parsePostfixExpression = parsePostfixExpression ;
extra . parsePrimaryExpression = parsePrimaryExpression ;
extra . parseProgram = parseProgram ;
extra . parsePropertyFunction = parsePropertyFunction ;
extra . parseSpreadOrAssignmentExpression = parseSpreadOrAssignmentExpression ;
extra . parseTemplateElement = parseTemplateElement ;
extra . parseTemplateLiteral = parseTemplateLiteral ;
2014-01-03 15:54:38 +00:00
extra . parseTypeAnnotatableIdentifier = parseTypeAnnotatableIdentifier ;
extra . parseTypeAnnotation = parseTypeAnnotation ;
2013-12-16 22:19:36 +00:00
extra . parseStatement = parseStatement ;
extra . parseSwitchCase = parseSwitchCase ;
extra . parseUnaryExpression = parseUnaryExpression ;
extra . parseVariableDeclaration = parseVariableDeclaration ;
extra . parseVariableIdentifier = parseVariableIdentifier ;
extra . parseMethodDefinition = parseMethodDefinition ;
extra . parseClassDeclaration = parseClassDeclaration ;
extra . parseClassExpression = parseClassExpression ;
extra . parseClassBody = parseClassBody ;
extra . parseXJSIdentifier = parseXJSIdentifier ;
extra . parseXJSChild = parseXJSChild ;
extra . parseXJSAttribute = parseXJSAttribute ;
extra . parseXJSAttributeValue = parseXJSAttributeValue ;
extra . parseXJSExpressionContainer = parseXJSExpressionContainer ;
extra . parseXJSEmptyExpression = parseXJSEmptyExpression ;
extra . parseXJSElement = parseXJSElement ;
extra . parseXJSClosingElement = parseXJSClosingElement ;
extra . parseXJSOpeningElement = parseXJSOpeningElement ;
parseAssignmentExpression = wrapTracking ( extra . parseAssignmentExpression ) ;
parseBinaryExpression = wrapTracking ( extra . parseBinaryExpression ) ;
parseBlock = wrapTracking ( extra . parseBlock ) ;
parseFunctionSourceElements = wrapTracking ( extra . parseFunctionSourceElements ) ;
parseCatchClause = wrapTracking ( extra . parseCatchClause ) ;
parseComputedMember = wrapTracking ( extra . parseComputedMember ) ;
parseConditionalExpression = wrapTracking ( extra . parseConditionalExpression ) ;
parseConstLetDeclaration = wrapTracking ( extra . parseConstLetDeclaration ) ;
parseExportBatchSpecifier = wrapTracking ( parseExportBatchSpecifier ) ;
parseExportDeclaration = wrapTracking ( parseExportDeclaration ) ;
parseExportSpecifier = wrapTracking ( parseExportSpecifier ) ;
parseExpression = wrapTracking ( extra . parseExpression ) ;
parseForVariableDeclaration = wrapTracking ( extra . parseForVariableDeclaration ) ;
parseFunctionDeclaration = wrapTracking ( extra . parseFunctionDeclaration ) ;
parseFunctionExpression = wrapTracking ( extra . parseFunctionExpression ) ;
parseParams = wrapTracking ( extra . parseParams ) ;
parseImportDeclaration = wrapTracking ( extra . parseImportDeclaration ) ;
parseImportSpecifier = wrapTracking ( extra . parseImportSpecifier ) ;
parseModuleDeclaration = wrapTracking ( extra . parseModuleDeclaration ) ;
parseModuleBlock = wrapTracking ( extra . parseModuleBlock ) ;
parseLeftHandSideExpression = wrapTracking ( parseLeftHandSideExpression ) ;
parseNewExpression = wrapTracking ( extra . parseNewExpression ) ;
parseNonComputedProperty = wrapTracking ( extra . parseNonComputedProperty ) ;
parseObjectProperty = wrapTracking ( extra . parseObjectProperty ) ;
parseObjectPropertyKey = wrapTracking ( extra . parseObjectPropertyKey ) ;
parsePostfixExpression = wrapTracking ( extra . parsePostfixExpression ) ;
parsePrimaryExpression = wrapTracking ( extra . parsePrimaryExpression ) ;
parseProgram = wrapTracking ( extra . parseProgram ) ;
parsePropertyFunction = wrapTracking ( extra . parsePropertyFunction ) ;
parseTemplateElement = wrapTracking ( extra . parseTemplateElement ) ;
parseTemplateLiteral = wrapTracking ( extra . parseTemplateLiteral ) ;
2014-01-03 15:54:38 +00:00
parseTypeAnnotatableIdentifier = wrapTracking ( extra . parseTypeAnnotatableIdentifier ) ;
parseTypeAnnotation = wrapTracking ( extra . parseTypeAnnotation ) ;
2013-12-16 22:19:36 +00:00
parseSpreadOrAssignmentExpression = wrapTracking ( extra . parseSpreadOrAssignmentExpression ) ;
parseStatement = wrapTracking ( extra . parseStatement ) ;
parseSwitchCase = wrapTracking ( extra . parseSwitchCase ) ;
parseUnaryExpression = wrapTracking ( extra . parseUnaryExpression ) ;
parseVariableDeclaration = wrapTracking ( extra . parseVariableDeclaration ) ;
parseVariableIdentifier = wrapTracking ( extra . parseVariableIdentifier ) ;
parseMethodDefinition = wrapTracking ( extra . parseMethodDefinition ) ;
parseClassDeclaration = wrapTracking ( extra . parseClassDeclaration ) ;
parseClassExpression = wrapTracking ( extra . parseClassExpression ) ;
parseClassBody = wrapTracking ( extra . parseClassBody ) ;
parseXJSIdentifier = wrapTracking ( extra . parseXJSIdentifier ) ;
parseXJSChild = wrapTrackingPreserveWhitespace ( extra . parseXJSChild ) ;
parseXJSAttribute = wrapTracking ( extra . parseXJSAttribute ) ;
parseXJSAttributeValue = wrapTracking ( extra . parseXJSAttributeValue ) ;
parseXJSExpressionContainer = wrapTracking ( extra . parseXJSExpressionContainer ) ;
parseXJSEmptyExpression = wrapTrackingPreserveWhitespace ( extra . parseXJSEmptyExpression ) ;
parseXJSElement = wrapTracking ( extra . parseXJSElement ) ;
parseXJSClosingElement = wrapTracking ( extra . parseXJSClosingElement ) ;
parseXJSOpeningElement = wrapTracking ( extra . parseXJSOpeningElement ) ;
}
if ( typeof extra . tokens !== 'undefined' ) {
extra . advance = advance ;
extra . scanRegExp = scanRegExp ;
advance = collectToken ;
scanRegExp = collectRegex ;
}
}
function unpatch ( ) {
if ( typeof extra . skipComment === 'function' ) {
skipComment = extra . skipComment ;
}
if ( extra . range || extra . loc ) {
parseAssignmentExpression = extra . parseAssignmentExpression ;
parseBinaryExpression = extra . parseBinaryExpression ;
parseBlock = extra . parseBlock ;
parseFunctionSourceElements = extra . parseFunctionSourceElements ;
parseCatchClause = extra . parseCatchClause ;
parseComputedMember = extra . parseComputedMember ;
parseConditionalExpression = extra . parseConditionalExpression ;
parseConstLetDeclaration = extra . parseConstLetDeclaration ;
parseExportBatchSpecifier = extra . parseExportBatchSpecifier ;
parseExportDeclaration = extra . parseExportDeclaration ;
parseExportSpecifier = extra . parseExportSpecifier ;
parseExpression = extra . parseExpression ;
parseForVariableDeclaration = extra . parseForVariableDeclaration ;
parseFunctionDeclaration = extra . parseFunctionDeclaration ;
parseFunctionExpression = extra . parseFunctionExpression ;
parseImportDeclaration = extra . parseImportDeclaration ;
parseImportSpecifier = extra . parseImportSpecifier ;
parseGroupExpression = extra . parseGroupExpression ;
parseLeftHandSideExpression = extra . parseLeftHandSideExpression ;
parseLeftHandSideExpressionAllowCall = extra . parseLeftHandSideExpressionAllowCall ;
parseModuleDeclaration = extra . parseModuleDeclaration ;
parseModuleBlock = extra . parseModuleBlock ;
parseNewExpression = extra . parseNewExpression ;
parseNonComputedProperty = extra . parseNonComputedProperty ;
parseObjectProperty = extra . parseObjectProperty ;
parseObjectPropertyKey = extra . parseObjectPropertyKey ;
parsePostfixExpression = extra . parsePostfixExpression ;
parsePrimaryExpression = extra . parsePrimaryExpression ;
parseProgram = extra . parseProgram ;
parsePropertyFunction = extra . parsePropertyFunction ;
parseTemplateElement = extra . parseTemplateElement ;
parseTemplateLiteral = extra . parseTemplateLiteral ;
2014-01-03 15:54:38 +00:00
parseTypeAnnotatableIdentifier = extra . parseTypeAnnotatableIdentifier ;
parseTypeAnnotation = extra . parseTypeAnnotation ;
2013-12-16 22:19:36 +00:00
parseSpreadOrAssignmentExpression = extra . parseSpreadOrAssignmentExpression ;
parseStatement = extra . parseStatement ;
parseSwitchCase = extra . parseSwitchCase ;
parseUnaryExpression = extra . parseUnaryExpression ;
parseVariableDeclaration = extra . parseVariableDeclaration ;
parseVariableIdentifier = extra . parseVariableIdentifier ;
parseMethodDefinition = extra . parseMethodDefinition ;
parseClassDeclaration = extra . parseClassDeclaration ;
parseClassExpression = extra . parseClassExpression ;
parseClassBody = extra . parseClassBody ;
parseXJSIdentifier = extra . parseXJSIdentifier ;
parseXJSChild = extra . parseXJSChild ;
parseXJSAttribute = extra . parseXJSAttribute ;
parseXJSAttributeValue = extra . parseXJSAttributeValue ;
parseXJSExpressionContainer = extra . parseXJSExpressionContainer ;
parseXJSEmptyExpression = extra . parseXJSEmptyExpression ;
parseXJSElement = extra . parseXJSElement ;
parseXJSClosingElement = extra . parseXJSClosingElement ;
parseXJSOpeningElement = extra . parseXJSOpeningElement ;
}
if ( typeof extra . scanRegExp === 'function' ) {
advance = extra . advance ;
scanRegExp = extra . scanRegExp ;
}
}
// This is used to modify the delegate.
function extend ( object , properties ) {
var entry , result = { } ;
for ( entry in object ) {
if ( object . hasOwnProperty ( entry ) ) {
result [ entry ] = object [ entry ] ;
}
}
for ( entry in properties ) {
if ( properties . hasOwnProperty ( entry ) ) {
result [ entry ] = properties [ entry ] ;
}
}
return result ;
}
function tokenize ( code , options ) {
var toString ,
token ,
tokens ;
toString = String ;
if ( typeof code !== 'string' && ! ( code instanceof String ) ) {
code = toString ( code ) ;
}
delegate = SyntaxTreeDelegate ;
source = code ;
index = 0 ;
lineNumber = ( source . length > 0 ) ? 1 : 0 ;
lineStart = 0 ;
length = source . length ;
lookahead = null ;
state = {
2014-01-03 15:54:38 +00:00
allowKeyword : true ,
2013-12-16 22:19:36 +00:00
allowIn : true ,
labelSet : { } ,
inFunctionBody : false ,
inIteration : false ,
inSwitch : false
} ;
extra = { } ;
// Options matching.
options = options || { } ;
// Of course we collect tokens here.
options . tokens = true ;
extra . tokens = [ ] ;
extra . tokenize = true ;
// The following two fields are necessary to compute the Regex tokens.
extra . openParenToken = - 1 ;
extra . openCurlyToken = - 1 ;
extra . range = ( typeof options . range === 'boolean' ) && options . range ;
extra . loc = ( typeof options . loc === 'boolean' ) && options . loc ;
if ( typeof options . comment === 'boolean' && options . comment ) {
extra . comments = [ ] ;
}
if ( typeof options . tolerant === 'boolean' && options . tolerant ) {
extra . errors = [ ] ;
}
if ( length > 0 ) {
if ( typeof source [ 0 ] === 'undefined' ) {
// Try first to convert to a string. This is good as fast path
// for old IE which understands string indexing for string
// literals only and not for string object.
if ( code instanceof String ) {
source = code . valueOf ( ) ;
}
}
}
patch ( ) ;
try {
peek ( ) ;
if ( lookahead . type === Token . EOF ) {
return extra . tokens ;
}
token = lex ( ) ;
while ( lookahead . type !== Token . EOF ) {
try {
token = lex ( ) ;
} catch ( lexError ) {
token = lookahead ;
if ( extra . errors ) {
extra . errors . push ( lexError ) ;
// We have to break on the first error
// to avoid infinite loops.
break ;
} else {
throw lexError ;
}
}
}
filterTokenLocation ( ) ;
tokens = extra . tokens ;
if ( typeof extra . comments !== 'undefined' ) {
filterCommentLocation ( ) ;
tokens . comments = extra . comments ;
}
if ( typeof extra . errors !== 'undefined' ) {
tokens . errors = extra . errors ;
}
} catch ( e ) {
throw e ;
} finally {
unpatch ( ) ;
extra = { } ;
}
return tokens ;
}
function parse ( code , options ) {
var program , toString ;
toString = String ;
if ( typeof code !== 'string' && ! ( code instanceof String ) ) {
code = toString ( code ) ;
}
delegate = SyntaxTreeDelegate ;
source = code ;
index = 0 ;
lineNumber = ( source . length > 0 ) ? 1 : 0 ;
lineStart = 0 ;
length = source . length ;
lookahead = null ;
state = {
2014-01-03 15:54:38 +00:00
allowKeyword : false ,
2013-12-16 22:19:36 +00:00
allowIn : true ,
labelSet : { } ,
parenthesizedCount : 0 ,
inFunctionBody : false ,
inIteration : false ,
inSwitch : false ,
yieldAllowed : false ,
yieldFound : false
} ;
extra = { } ;
if ( typeof options !== 'undefined' ) {
extra . range = ( typeof options . range === 'boolean' ) && options . range ;
extra . loc = ( typeof options . loc === 'boolean' ) && options . loc ;
if ( extra . loc && options . source !== null && options . source !== undefined ) {
delegate = extend ( delegate , {
'postProcess' : function ( node ) {
node . loc . source = toString ( options . source ) ;
return node ;
}
} ) ;
}
if ( typeof options . tokens === 'boolean' && options . tokens ) {
extra . tokens = [ ] ;
}
if ( typeof options . comment === 'boolean' && options . comment ) {
extra . comments = [ ] ;
}
if ( typeof options . tolerant === 'boolean' && options . tolerant ) {
extra . errors = [ ] ;
}
}
if ( length > 0 ) {
if ( typeof source [ 0 ] === 'undefined' ) {
// Try first to convert to a string. This is good as fast path
// for old IE which understands string indexing for string
// literals only and not for string object.
if ( code instanceof String ) {
source = code . valueOf ( ) ;
}
}
}
patch ( ) ;
try {
program = parseProgram ( ) ;
if ( typeof extra . comments !== 'undefined' ) {
filterCommentLocation ( ) ;
program . comments = extra . comments ;
}
if ( typeof extra . tokens !== 'undefined' ) {
filterTokenLocation ( ) ;
program . tokens = extra . tokens ;
}
if ( typeof extra . errors !== 'undefined' ) {
program . errors = extra . errors ;
}
if ( extra . range || extra . loc ) {
program . body = filterGroup ( program . body ) ;
}
} catch ( e ) {
throw e ;
} finally {
unpatch ( ) ;
extra = { } ;
}
return program ;
}
// Sync with package.json and component.json.
exports . version = '1.1.0-dev-harmony' ;
exports . tokenize = tokenize ;
exports . parse = parse ;
// Deep copy.
exports . Syntax = ( function ( ) {
var name , types = { } ;
if ( typeof Object . create === 'function' ) {
types = Object . create ( null ) ;
}
for ( name in Syntax ) {
if ( Syntax . hasOwnProperty ( name ) ) {
types [ name ] = Syntax [ name ] ;
}
}
if ( typeof Object . freeze === 'function' ) {
Object . freeze ( types ) ;
}
return types ;
} ( ) ) ;
} ) ) ;
/* vim: set sw=4 ts=4 et tw=80 : */
2014-01-03 15:54:38 +00:00
} , { } ] , 6 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
var Base62 = ( function ( my ) {
my . chars = [ "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" , "u" , "v" , "w" , "x" , "y" , "z" , "A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" , "I" , "J" , "K" , "L" , "M" , "N" , "O" , "P" , "Q" , "R" , "S" , "T" , "U" , "V" , "W" , "X" , "Y" , "Z" ]
my . encode = function ( i ) {
if ( i === 0 ) { return '0' }
var s = ''
while ( i > 0 ) {
s = this . chars [ i % 62 ] + s
i = Math . floor ( i / 62 )
}
return s
} ;
my . decode = function ( a , b , c , d ) {
for (
b = c = (
a === ( /\W|_|^$/ . test ( a += "" ) || a )
) - 1 ;
d = a . charCodeAt ( c ++ ) ;
)
b = b * 62 + d - [ , 48 , 29 , 87 ] [ d >> 5 ] ;
return b
} ;
return my ;
} ( { } ) ) ;
module . exports = Base62
2014-01-03 15:54:38 +00:00
} , { } ] , 7 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ *
* Copyright 2009 - 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE . txt or :
* http : //opensource.org/licenses/BSD-3-Clause
* /
exports . SourceMapGenerator = require ( './source-map/source-map-generator' ) . SourceMapGenerator ;
exports . SourceMapConsumer = require ( './source-map/source-map-consumer' ) . SourceMapConsumer ;
exports . SourceNode = require ( './source-map/source-node' ) . SourceNode ;
2014-01-03 15:54:38 +00:00
} , { "./source-map/source-map-consumer" : 12 , "./source-map/source-map-generator" : 13 , "./source-map/source-node" : 14 } ] , 8 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/* -*- Mode: js; js-indent-level: 2; -*- */
/ *
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE or :
* http : //opensource.org/licenses/BSD-3-Clause
* /
if ( typeof define !== 'function' ) {
var define = require ( 'amdefine' ) ( module ) ;
}
define ( function ( require , exports , module ) {
/ * *
* A data structure which is a combination of an array and a set . Adding a new
* member is O ( 1 ) , testing for membership is O ( 1 ) , and finding the index of an
* element is O ( 1 ) . Removing elements from the set is not supported . Only
* strings are supported for membership .
* /
function ArraySet ( ) {
this . _array = [ ] ;
this . _set = { } ;
}
/ * *
* Static method for creating ArraySet instances from an existing array .
* /
ArraySet . fromArray = function ArraySet _fromArray ( aArray ) {
var set = new ArraySet ( ) ;
for ( var i = 0 , len = aArray . length ; i < len ; i ++ ) {
set . add ( aArray [ i ] ) ;
}
return set ;
} ;
/ * *
* Because behavior goes wacky when you set ` __proto__ ` on ` this._set ` , we
* have to prefix all the strings in our set with an arbitrary character .
*
* See https : //github.com/mozilla/source-map/pull/31 and
* https : //github.com/mozilla/source-map/issues/30
*
* @ param String aStr
* /
ArraySet . prototype . _toSetString = function ArraySet _ _toSetString ( aStr ) {
return "$" + aStr ;
} ;
/ * *
* Add the given string to this set .
*
* @ param String aStr
* /
ArraySet . prototype . add = function ArraySet _add ( aStr ) {
if ( this . has ( aStr ) ) {
// Already a member; nothing to do.
return ;
}
var idx = this . _array . length ;
this . _array . push ( aStr ) ;
this . _set [ this . _toSetString ( aStr ) ] = idx ;
} ;
/ * *
* Is the given string a member of this set ?
*
* @ param String aStr
* /
ArraySet . prototype . has = function ArraySet _has ( aStr ) {
return Object . prototype . hasOwnProperty . call ( this . _set ,
this . _toSetString ( aStr ) ) ;
} ;
/ * *
* What is the index of the given string in the array ?
*
* @ param String aStr
* /
ArraySet . prototype . indexOf = function ArraySet _indexOf ( aStr ) {
if ( this . has ( aStr ) ) {
return this . _set [ this . _toSetString ( aStr ) ] ;
}
throw new Error ( '"' + aStr + '" is not in the set.' ) ;
} ;
/ * *
* What is the element at the given index ?
*
* @ param Number aIdx
* /
ArraySet . prototype . at = function ArraySet _at ( aIdx ) {
if ( aIdx >= 0 && aIdx < this . _array . length ) {
return this . _array [ aIdx ] ;
}
throw new Error ( 'No element indexed by ' + aIdx ) ;
} ;
/ * *
* Returns the array representation of this set ( which has the proper indices
* indicated by indexOf ) . Note that this is a copy of the internal array used
* for storing the members so that no one can mess with internal state .
* /
ArraySet . prototype . toArray = function ArraySet _toArray ( ) {
return this . _array . slice ( ) ;
} ;
exports . ArraySet = ArraySet ;
} ) ;
2014-01-03 15:54:38 +00:00
} , { "amdefine" : 16 } ] , 9 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/* -*- Mode: js; js-indent-level: 2; -*- */
/ *
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE or :
* http : //opensource.org/licenses/BSD-3-Clause
*
* Based on the Base 64 VLQ implementation in Closure Compiler :
* https : //code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
*
* Copyright 2011 The Closure Compiler Authors . All rights reserved .
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are
* met :
*
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above
* copyright notice , this list of conditions and the following
* disclaimer in the documentation and / or other materials provided
* with the distribution .
* * Neither the name of Google Inc . nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
if ( typeof define !== 'function' ) {
var define = require ( 'amdefine' ) ( module ) ;
}
define ( function ( require , exports , module ) {
var base64 = require ( './base64' ) ;
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
// Continuation
// | Sign
// | |
// V V
// 101011
var VLQ _BASE _SHIFT = 5 ;
// binary: 100000
var VLQ _BASE = 1 << VLQ _BASE _SHIFT ;
// binary: 011111
var VLQ _BASE _MASK = VLQ _BASE - 1 ;
// binary: 100000
var VLQ _CONTINUATION _BIT = VLQ _BASE ;
/ * *
* Converts from a two - complement value to a value where the sign bit is
* is placed in the least significant bit . For example , as decimals :
* 1 becomes 2 ( 10 binary ) , - 1 becomes 3 ( 11 binary )
* 2 becomes 4 ( 100 binary ) , - 2 becomes 5 ( 101 binary )
* /
function toVLQSigned ( aValue ) {
return aValue < 0
? ( ( - aValue ) << 1 ) + 1
: ( aValue << 1 ) + 0 ;
}
/ * *
* Converts to a two - complement value from a value where the sign bit is
* is placed in the least significant bit . For example , as decimals :
* 2 ( 10 binary ) becomes 1 , 3 ( 11 binary ) becomes - 1
* 4 ( 100 binary ) becomes 2 , 5 ( 101 binary ) becomes - 2
* /
function fromVLQSigned ( aValue ) {
var isNegative = ( aValue & 1 ) === 1 ;
var shifted = aValue >> 1 ;
return isNegative
? - shifted
: shifted ;
}
/ * *
* Returns the base 64 VLQ encoded value .
* /
exports . encode = function base64VLQ _encode ( aValue ) {
var encoded = "" ;
var digit ;
var vlq = toVLQSigned ( aValue ) ;
do {
digit = vlq & VLQ _BASE _MASK ;
vlq >>>= VLQ _BASE _SHIFT ;
if ( vlq > 0 ) {
// There are still more digits in this value, so we must make sure the
// continuation bit is marked.
digit |= VLQ _CONTINUATION _BIT ;
}
encoded += base64 . encode ( digit ) ;
} while ( vlq > 0 ) ;
return encoded ;
} ;
/ * *
* Decodes the next base 64 VLQ value from the given string and returns the
* value and the rest of the string .
* /
exports . decode = function base64VLQ _decode ( aStr ) {
var i = 0 ;
var strLen = aStr . length ;
var result = 0 ;
var shift = 0 ;
var continuation , digit ;
do {
if ( i >= strLen ) {
throw new Error ( "Expected more digits in base 64 VLQ value." ) ;
}
digit = base64 . decode ( aStr . charAt ( i ++ ) ) ;
continuation = ! ! ( digit & VLQ _CONTINUATION _BIT ) ;
digit &= VLQ _BASE _MASK ;
result = result + ( digit << shift ) ;
shift += VLQ _BASE _SHIFT ;
} while ( continuation ) ;
return {
value : fromVLQSigned ( result ) ,
rest : aStr . slice ( i )
} ;
} ;
} ) ;
2014-01-03 15:54:38 +00:00
} , { "./base64" : 10 , "amdefine" : 16 } ] , 10 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/* -*- Mode: js; js-indent-level: 2; -*- */
/ *
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE or :
* http : //opensource.org/licenses/BSD-3-Clause
* /
if ( typeof define !== 'function' ) {
var define = require ( 'amdefine' ) ( module ) ;
}
define ( function ( require , exports , module ) {
var charToIntMap = { } ;
var intToCharMap = { } ;
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
. split ( '' )
. forEach ( function ( ch , index ) {
charToIntMap [ ch ] = index ;
intToCharMap [ index ] = ch ;
} ) ;
/ * *
* Encode an integer in the range of 0 to 63 to a single base 64 digit .
* /
exports . encode = function base64 _encode ( aNumber ) {
if ( aNumber in intToCharMap ) {
return intToCharMap [ aNumber ] ;
}
throw new TypeError ( "Must be between 0 and 63: " + aNumber ) ;
} ;
/ * *
* Decode a single base 64 digit to an integer .
* /
exports . decode = function base64 _decode ( aChar ) {
if ( aChar in charToIntMap ) {
return charToIntMap [ aChar ] ;
}
throw new TypeError ( "Not a valid base 64 digit: " + aChar ) ;
} ;
} ) ;
2014-01-03 15:54:38 +00:00
} , { "amdefine" : 16 } ] , 11 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/* -*- Mode: js; js-indent-level: 2; -*- */
/ *
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE or :
* http : //opensource.org/licenses/BSD-3-Clause
* /
if ( typeof define !== 'function' ) {
var define = require ( 'amdefine' ) ( module ) ;
}
define ( function ( require , exports , module ) {
/ * *
* Recursive implementation of binary search .
*
* @ param aLow Indices here and lower do not contain the needle .
* @ param aHigh Indices here and higher do not contain the needle .
* @ param aNeedle The element being searched for .
* @ param aHaystack The non - empty array being searched .
* @ param aCompare Function which takes two elements and returns - 1 , 0 , or 1.
* /
function recursiveSearch ( aLow , aHigh , aNeedle , aHaystack , aCompare ) {
// This function terminates when one of the following is true:
//
// 1. We find the exact element we are looking for.
//
// 2. We did not find the exact element, but we can return the next
// closest element that is less than that element.
//
// 3. We did not find the exact element, and there is no next-closest
// element which is less than the one we are searching for, so we
// return null.
var mid = Math . floor ( ( aHigh - aLow ) / 2 ) + aLow ;
var cmp = aCompare ( aNeedle , aHaystack [ mid ] ) ;
if ( cmp === 0 ) {
// Found the element we are looking for.
return aHaystack [ mid ] ;
}
else if ( cmp > 0 ) {
// aHaystack[mid] is greater than our needle.
if ( aHigh - mid > 1 ) {
// The element is in the upper half.
return recursiveSearch ( mid , aHigh , aNeedle , aHaystack , aCompare ) ;
}
// We did not find an exact match, return the next closest one
// (termination case 2).
return aHaystack [ mid ] ;
}
else {
// aHaystack[mid] is less than our needle.
if ( mid - aLow > 1 ) {
// The element is in the lower half.
return recursiveSearch ( aLow , mid , aNeedle , aHaystack , aCompare ) ;
}
// The exact needle element was not found in this haystack. Determine if
// we are in termination case (2) or (3) and return the appropriate thing.
return aLow < 0
? null
: aHaystack [ aLow ] ;
}
}
/ * *
* This is an implementation of binary search which will always try and return
* the next lowest value checked if there is no exact hit . This is because
* mappings between original and generated line / col pairs are single points ,
* and there is an implicit region between each of them , so a miss just means
* that you aren ' t on the very start of a region .
*
* @ param aNeedle The element you are looking for .
* @ param aHaystack The array that is being searched .
* @ param aCompare A function which takes the needle and an element in the
* array and returns - 1 , 0 , or 1 depending on whether the needle is less
* than , equal to , or greater than the element , respectively .
* /
exports . search = function search ( aNeedle , aHaystack , aCompare ) {
return aHaystack . length > 0
? recursiveSearch ( - 1 , aHaystack . length , aNeedle , aHaystack , aCompare )
: null ;
} ;
} ) ;
2014-01-03 15:54:38 +00:00
} , { "amdefine" : 16 } ] , 12 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/* -*- Mode: js; js-indent-level: 2; -*- */
/ *
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE or :
* http : //opensource.org/licenses/BSD-3-Clause
* /
if ( typeof define !== 'function' ) {
var define = require ( 'amdefine' ) ( module ) ;
}
define ( function ( require , exports , module ) {
var util = require ( './util' ) ;
var binarySearch = require ( './binary-search' ) ;
var ArraySet = require ( './array-set' ) . ArraySet ;
var base64VLQ = require ( './base64-vlq' ) ;
/ * *
* A SourceMapConsumer instance represents a parsed source map which we can
* query for information about the original file positions by giving it a file
* position in the generated source .
*
* The only parameter is the raw source map ( either as a JSON string , or
* already parsed to an object ) . According to the spec , source maps have the
* following attributes :
*
* - version : Which version of the source map spec this map is following .
* - sources : An array of URLs to the original source files .
* - names : An array of identifiers which can be referrenced by individual mappings .
* - sourceRoot : Optional . The URL root from which all sources are relative .
* - mappings : A string of base64 VLQs which contain the actual mappings .
* - file : The generated file this source map is associated with .
*
* Here is an example source map , taken from the source map spec [ 0 ] :
*
* {
* version : 3 ,
* file : "out.js" ,
* sourceRoot : "" ,
* sources : [ "foo.js" , "bar.js" ] ,
* names : [ "src" , "maps" , "are" , "fun" ] ,
* mappings : "AA,AB;;ABCDE;"
* }
*
* [ 0 ] : https : //docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
* /
function SourceMapConsumer ( aSourceMap ) {
var sourceMap = aSourceMap ;
if ( typeof aSourceMap === 'string' ) {
sourceMap = JSON . parse ( aSourceMap . replace ( /^\)\]\}'/ , '' ) ) ;
}
var version = util . getArg ( sourceMap , 'version' ) ;
var sources = util . getArg ( sourceMap , 'sources' ) ;
var names = util . getArg ( sourceMap , 'names' ) ;
var sourceRoot = util . getArg ( sourceMap , 'sourceRoot' , null ) ;
var mappings = util . getArg ( sourceMap , 'mappings' ) ;
var file = util . getArg ( sourceMap , 'file' ) ;
if ( version !== this . _version ) {
throw new Error ( 'Unsupported version: ' + version ) ;
}
this . _names = ArraySet . fromArray ( names ) ;
this . _sources = ArraySet . fromArray ( sources ) ;
this . _sourceRoot = sourceRoot ;
this . file = file ;
// `this._generatedMappings` and `this._originalMappings` hold the parsed
// mapping coordinates from the source map's "mappings" attribute. Each
// object in the array is of the form
//
// {
// generatedLine: The line number in the generated code,
// generatedColumn: The column number in the generated code,
// source: The path to the original source file that generated this
// chunk of code,
// originalLine: The line number in the original source that
// corresponds to this chunk of generated code,
// originalColumn: The column number in the original source that
// corresponds to this chunk of generated code,
// name: The name of the original symbol which generated this chunk of
// code.
// }
//
// All properties except for `generatedLine` and `generatedColumn` can be
// `null`.
//
// `this._generatedMappings` is ordered by the generated positions.
//
// `this._originalMappings` is ordered by the original positions.
this . _generatedMappings = [ ] ;
this . _originalMappings = [ ] ;
this . _parseMappings ( mappings , sourceRoot ) ;
}
/ * *
* The version of the source mapping spec that we are consuming .
* /
SourceMapConsumer . prototype . _version = 3 ;
/ * *
* The list of original sources .
* /
Object . defineProperty ( SourceMapConsumer . prototype , 'sources' , {
get : function ( ) {
return this . _sources . toArray ( ) . map ( function ( s ) {
return this . _sourceRoot ? util . join ( this . _sourceRoot , s ) : s ;
} , this ) ;
}
} ) ;
/ * *
* Parse the mappings in a string in to a data structure which we can easily
* query ( an ordered list in this . _generatedMappings ) .
* /
SourceMapConsumer . prototype . _parseMappings =
function SourceMapConsumer _parseMappings ( aStr , aSourceRoot ) {
var generatedLine = 1 ;
var previousGeneratedColumn = 0 ;
var previousOriginalLine = 0 ;
var previousOriginalColumn = 0 ;
var previousSource = 0 ;
var previousName = 0 ;
var mappingSeparator = /^[,;]/ ;
var str = aStr ;
var mapping ;
var temp ;
while ( str . length > 0 ) {
if ( str . charAt ( 0 ) === ';' ) {
generatedLine ++ ;
str = str . slice ( 1 ) ;
previousGeneratedColumn = 0 ;
}
else if ( str . charAt ( 0 ) === ',' ) {
str = str . slice ( 1 ) ;
}
else {
mapping = { } ;
mapping . generatedLine = generatedLine ;
// Generated column.
temp = base64VLQ . decode ( str ) ;
mapping . generatedColumn = previousGeneratedColumn + temp . value ;
previousGeneratedColumn = mapping . generatedColumn ;
str = temp . rest ;
if ( str . length > 0 && ! mappingSeparator . test ( str . charAt ( 0 ) ) ) {
// Original source.
temp = base64VLQ . decode ( str ) ;
if ( aSourceRoot ) {
mapping . source = util . join ( aSourceRoot , this . _sources . at ( previousSource + temp . value ) ) ;
}
else {
mapping . source = this . _sources . at ( previousSource + temp . value ) ;
}
previousSource += temp . value ;
str = temp . rest ;
if ( str . length === 0 || mappingSeparator . test ( str . charAt ( 0 ) ) ) {
throw new Error ( 'Found a source, but no line and column' ) ;
}
// Original line.
temp = base64VLQ . decode ( str ) ;
mapping . originalLine = previousOriginalLine + temp . value ;
previousOriginalLine = mapping . originalLine ;
// Lines are stored 0-based
mapping . originalLine += 1 ;
str = temp . rest ;
if ( str . length === 0 || mappingSeparator . test ( str . charAt ( 0 ) ) ) {
throw new Error ( 'Found a source and line, but no column' ) ;
}
// Original column.
temp = base64VLQ . decode ( str ) ;
mapping . originalColumn = previousOriginalColumn + temp . value ;
previousOriginalColumn = mapping . originalColumn ;
str = temp . rest ;
if ( str . length > 0 && ! mappingSeparator . test ( str . charAt ( 0 ) ) ) {
// Original name.
temp = base64VLQ . decode ( str ) ;
mapping . name = this . _names . at ( previousName + temp . value ) ;
previousName += temp . value ;
str = temp . rest ;
}
}
this . _generatedMappings . push ( mapping ) ;
this . _originalMappings . push ( mapping ) ;
}
}
this . _originalMappings . sort ( this . _compareOriginalPositions ) ;
} ;
/ * *
* Comparator between two mappings where the original positions are compared .
* /
SourceMapConsumer . prototype . _compareOriginalPositions =
function SourceMapConsumer _compareOriginalPositions ( mappingA , mappingB ) {
if ( mappingA . source > mappingB . source ) {
return 1 ;
}
else if ( mappingA . source < mappingB . source ) {
return - 1 ;
}
else {
var cmp = mappingA . originalLine - mappingB . originalLine ;
return cmp === 0
? mappingA . originalColumn - mappingB . originalColumn
: cmp ;
}
} ;
/ * *
* Comparator between two mappings where the generated positions are compared .
* /
SourceMapConsumer . prototype . _compareGeneratedPositions =
function SourceMapConsumer _compareGeneratedPositions ( mappingA , mappingB ) {
var cmp = mappingA . generatedLine - mappingB . generatedLine ;
return cmp === 0
? mappingA . generatedColumn - mappingB . generatedColumn
: cmp ;
} ;
/ * *
* Find the mapping that best matches the hypothetical "needle" mapping that
* we are searching for in the given "haystack" of mappings .
* /
SourceMapConsumer . prototype . _findMapping =
function SourceMapConsumer _findMapping ( aNeedle , aMappings , aLineName ,
aColumnName , aComparator ) {
// To return the position we are searching for, we must first find the
// mapping for the given position and then return the opposite position it
// points to. Because the mappings are sorted, we can use binary search to
// find the best mapping.
if ( aNeedle [ aLineName ] <= 0 ) {
throw new TypeError ( 'Line must be greater than or equal to 1, got '
+ aNeedle [ aLineName ] ) ;
}
if ( aNeedle [ aColumnName ] < 0 ) {
throw new TypeError ( 'Column must be greater than or equal to 0, got '
+ aNeedle [ aColumnName ] ) ;
}
return binarySearch . search ( aNeedle , aMappings , aComparator ) ;
} ;
/ * *
* Returns the original source , line , and column information for the generated
* source ' s line and column positions provided . The only argument is an object
* with the following properties :
*
* - line : The line number in the generated source .
* - column : The column number in the generated source .
*
* and an object is returned with the following properties :
*
* - source : The original source file , or null .
* - line : The line number in the original source , or null .
* - column : The column number in the original source , or null .
* - name : The original identifier , or null .
* /
SourceMapConsumer . prototype . originalPositionFor =
function SourceMapConsumer _originalPositionFor ( aArgs ) {
var needle = {
generatedLine : util . getArg ( aArgs , 'line' ) ,
generatedColumn : util . getArg ( aArgs , 'column' )
} ;
var mapping = this . _findMapping ( needle ,
this . _generatedMappings ,
"generatedLine" ,
"generatedColumn" ,
this . _compareGeneratedPositions )
if ( mapping ) {
return {
source : util . getArg ( mapping , 'source' , null ) ,
line : util . getArg ( mapping , 'originalLine' , null ) ,
column : util . getArg ( mapping , 'originalColumn' , null ) ,
name : util . getArg ( mapping , 'name' , null )
} ;
}
return {
source : null ,
line : null ,
column : null ,
name : null
} ;
} ;
/ * *
* Returns the generated line and column information for the original source ,
* line , and column positions provided . The only argument is an object with
* the following properties :
*
* - source : The filename of the original source .
* - line : The line number in the original source .
* - column : The column number in the original source .
*
* and an object is returned with the following properties :
*
* - line : The line number in the generated source , or null .
* - column : The column number in the generated source , or null .
* /
SourceMapConsumer . prototype . generatedPositionFor =
function SourceMapConsumer _generatedPositionFor ( aArgs ) {
var needle = {
source : util . getArg ( aArgs , 'source' ) ,
originalLine : util . getArg ( aArgs , 'line' ) ,
originalColumn : util . getArg ( aArgs , 'column' )
} ;
var mapping = this . _findMapping ( needle ,
this . _originalMappings ,
"originalLine" ,
"originalColumn" ,
this . _compareOriginalPositions )
if ( mapping ) {
return {
line : util . getArg ( mapping , 'generatedLine' , null ) ,
column : util . getArg ( mapping , 'generatedColumn' , null )
} ;
}
return {
line : null ,
column : null
} ;
} ;
SourceMapConsumer . GENERATED _ORDER = 1 ;
SourceMapConsumer . ORIGINAL _ORDER = 2 ;
/ * *
* Iterate over each mapping between an original source / line / column and a
* generated line / column in this source map .
*
* @ param Function aCallback
* The function that is called with each mapping . This function should
* not mutate the mapping .
* @ param Object aContext
* Optional . If specified , this object will be the value of ` this ` every
* time that ` aCallback ` is called .
* @ param aOrder
* Either ` SourceMapConsumer.GENERATED_ORDER ` or
* ` SourceMapConsumer.ORIGINAL_ORDER ` . Specifies whether you want to
* iterate over the mappings sorted by the generated file ' s line / column
* order or the original ' s source / line / column order , respectively . Defaults to
* ` SourceMapConsumer.GENERATED_ORDER ` .
* /
SourceMapConsumer . prototype . eachMapping =
function SourceMapConsumer _eachMapping ( aCallback , aContext , aOrder ) {
var context = aContext || null ;
var order = aOrder || SourceMapConsumer . GENERATED _ORDER ;
var mappings ;
switch ( order ) {
case SourceMapConsumer . GENERATED _ORDER :
mappings = this . _generatedMappings ;
break ;
case SourceMapConsumer . ORIGINAL _ORDER :
mappings = this . _originalMappings ;
break ;
default :
throw new Error ( "Unknown order of iteration." ) ;
}
mappings . forEach ( aCallback , context ) ;
} ;
exports . SourceMapConsumer = SourceMapConsumer ;
} ) ;
2014-01-03 15:54:38 +00:00
} , { "./array-set" : 8 , "./base64-vlq" : 9 , "./binary-search" : 11 , "./util" : 15 , "amdefine" : 16 } ] , 13 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/* -*- Mode: js; js-indent-level: 2; -*- */
/ *
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE or :
* http : //opensource.org/licenses/BSD-3-Clause
* /
if ( typeof define !== 'function' ) {
var define = require ( 'amdefine' ) ( module ) ;
}
define ( function ( require , exports , module ) {
var base64VLQ = require ( './base64-vlq' ) ;
var util = require ( './util' ) ;
var ArraySet = require ( './array-set' ) . ArraySet ;
/ * *
* An instance of the SourceMapGenerator represents a source map which is
* being built incrementally . To create a new one , you must pass an object
* with the following properties :
*
* - file : The filename of the generated source .
* - sourceRoot : An optional root for all URLs in this source map .
* /
function SourceMapGenerator ( aArgs ) {
this . _file = util . getArg ( aArgs , 'file' ) ;
this . _sourceRoot = util . getArg ( aArgs , 'sourceRoot' , null ) ;
this . _sources = new ArraySet ( ) ;
this . _names = new ArraySet ( ) ;
this . _mappings = [ ] ;
}
SourceMapGenerator . prototype . _version = 3 ;
/ * *
* Add a single mapping from original source line and column to the generated
* source ' s line and column for this source map being created . The mapping
* object should have the following properties :
*
* - generated : An object with the generated line and column positions .
* - original : An object with the original line and column positions .
* - source : The original source file ( relative to the sourceRoot ) .
* - name : An optional original token name for this mapping .
* /
SourceMapGenerator . prototype . addMapping =
function SourceMapGenerator _addMapping ( aArgs ) {
var generated = util . getArg ( aArgs , 'generated' ) ;
var original = util . getArg ( aArgs , 'original' , null ) ;
var source = util . getArg ( aArgs , 'source' , null ) ;
var name = util . getArg ( aArgs , 'name' , null ) ;
this . _validateMapping ( generated , original , source , name ) ;
if ( source && ! this . _sources . has ( source ) ) {
this . _sources . add ( source ) ;
}
if ( name && ! this . _names . has ( name ) ) {
this . _names . add ( name ) ;
}
this . _mappings . push ( {
generated : generated ,
original : original ,
source : source ,
name : name
} ) ;
} ;
/ * *
* A mapping can have one of the three levels of data :
*
* 1. Just the generated position .
* 2. The Generated position , original position , and original source .
* 3. Generated and original position , original source , as well as a name
* token .
*
* To maintain consistency , we validate that any new mapping being added falls
* in to one of these categories .
* /
SourceMapGenerator . prototype . _validateMapping =
function SourceMapGenerator _validateMapping ( aGenerated , aOriginal , aSource ,
aName ) {
if ( aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated . line > 0 && aGenerated . column >= 0
&& ! aOriginal && ! aSource && ! aName ) {
// Case 1.
return ;
}
else if ( aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
&& aGenerated . line > 0 && aGenerated . column >= 0
&& aOriginal . line > 0 && aOriginal . column >= 0
&& aSource ) {
// Cases 2 and 3.
return ;
}
else {
throw new Error ( 'Invalid mapping.' ) ;
}
} ;
/ * *
* Serialize the accumulated mappings in to the stream of base 64 VLQs
* specified by the source map format .
* /
SourceMapGenerator . prototype . _serializeMappings =
function SourceMapGenerator _serializeMappings ( ) {
var previousGeneratedColumn = 0 ;
var previousGeneratedLine = 1 ;
var previousOriginalColumn = 0 ;
var previousOriginalLine = 0 ;
var previousName = 0 ;
var previousSource = 0 ;
var result = '' ;
var mapping ;
// The mappings must be guarenteed to be in sorted order before we start
// serializing them or else the generated line numbers (which are defined
// via the ';' separators) will be all messed up. Note: it might be more
// performant to maintain the sorting as we insert them, rather than as we
// serialize them, but the big O is the same either way.
this . _mappings . sort ( function ( mappingA , mappingB ) {
var cmp = mappingA . generated . line - mappingB . generated . line ;
return cmp === 0
? mappingA . generated . column - mappingB . generated . column
: cmp ;
} ) ;
for ( var i = 0 , len = this . _mappings . length ; i < len ; i ++ ) {
mapping = this . _mappings [ i ] ;
if ( mapping . generated . line !== previousGeneratedLine ) {
previousGeneratedColumn = 0 ;
while ( mapping . generated . line !== previousGeneratedLine ) {
result += ';' ;
previousGeneratedLine ++ ;
}
}
else {
if ( i > 0 ) {
result += ',' ;
}
}
result += base64VLQ . encode ( mapping . generated . column
- previousGeneratedColumn ) ;
previousGeneratedColumn = mapping . generated . column ;
if ( mapping . source && mapping . original ) {
result += base64VLQ . encode ( this . _sources . indexOf ( mapping . source )
- previousSource ) ;
previousSource = this . _sources . indexOf ( mapping . source ) ;
// lines are stored 0-based in SourceMap spec version 3
result += base64VLQ . encode ( mapping . original . line - 1
- previousOriginalLine ) ;
previousOriginalLine = mapping . original . line - 1 ;
result += base64VLQ . encode ( mapping . original . column
- previousOriginalColumn ) ;
previousOriginalColumn = mapping . original . column ;
if ( mapping . name ) {
result += base64VLQ . encode ( this . _names . indexOf ( mapping . name )
- previousName ) ;
previousName = this . _names . indexOf ( mapping . name ) ;
}
}
}
return result ;
} ;
/ * *
* Externalize the source map .
* /
SourceMapGenerator . prototype . toJSON =
function SourceMapGenerator _toJSON ( ) {
var map = {
version : this . _version ,
file : this . _file ,
sources : this . _sources . toArray ( ) ,
names : this . _names . toArray ( ) ,
mappings : this . _serializeMappings ( )
} ;
if ( this . _sourceRoot ) {
map . sourceRoot = this . _sourceRoot ;
}
return map ;
} ;
/ * *
* Render the source map being generated to a string .
* /
SourceMapGenerator . prototype . toString =
function SourceMapGenerator _toString ( ) {
return JSON . stringify ( this ) ;
} ;
exports . SourceMapGenerator = SourceMapGenerator ;
} ) ;
2014-01-03 15:54:38 +00:00
} , { "./array-set" : 8 , "./base64-vlq" : 9 , "./util" : 15 , "amdefine" : 16 } ] , 14 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/* -*- Mode: js; js-indent-level: 2; -*- */
/ *
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE or :
* http : //opensource.org/licenses/BSD-3-Clause
* /
if ( typeof define !== 'function' ) {
var define = require ( 'amdefine' ) ( module ) ;
}
define ( function ( require , exports , module ) {
var SourceMapGenerator = require ( './source-map-generator' ) . SourceMapGenerator ;
/ * *
* SourceNodes provide a way to abstract over interpolating / concatenating
* snippets of generated JavaScript source code while maintaining the line and
* column information associated with the original source code .
*
* @ param aLine The original line number .
* @ param aColumn The original column number .
* @ param aSource The original source ' s filename .
* @ param aChunks Optional . An array of strings which are snippets of
* generated JS , or other SourceNodes .
* /
function SourceNode ( aLine , aColumn , aSource , aChunks ) {
this . children = [ ] ;
this . line = aLine ;
this . column = aColumn ;
this . source = aSource ;
if ( aChunks != null ) this . add ( aChunks ) ;
}
/ * *
* Add a chunk of generated JS to this source node .
*
* @ param aChunk A string snippet of generated JS code , another instance of
* SourceNode , or an array where each member is one of those things .
* /
SourceNode . prototype . add = function SourceNode _add ( aChunk ) {
if ( Array . isArray ( aChunk ) ) {
aChunk . forEach ( function ( chunk ) {
this . add ( chunk ) ;
} , this ) ;
}
else if ( aChunk instanceof SourceNode || typeof aChunk === "string" ) {
if ( aChunk ) {
this . children . push ( aChunk ) ;
}
}
else {
throw new TypeError (
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
) ;
}
return this ;
} ;
/ * *
* Add a chunk of generated JS to the beginning of this source node .
*
* @ param aChunk A string snippet of generated JS code , another instance of
* SourceNode , or an array where each member is one of those things .
* /
SourceNode . prototype . prepend = function SourceNode _prepend ( aChunk ) {
if ( Array . isArray ( aChunk ) ) {
for ( var i = aChunk . length - 1 ; i >= 0 ; i -- ) {
this . prepend ( aChunk [ i ] ) ;
}
}
else if ( aChunk instanceof SourceNode || typeof aChunk === "string" ) {
this . children . unshift ( aChunk ) ;
}
else {
throw new TypeError (
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
) ;
}
return this ;
} ;
/ * *
* Walk over the tree of JS snippets in this node and its children . The
* walking function is called once for each snippet of JS and is passed that
* snippet and the its original associated source ' s line / column location .
*
* @ param aFn The traversal function .
* /
SourceNode . prototype . walk = function SourceNode _walk ( aFn ) {
this . children . forEach ( function ( chunk ) {
if ( chunk instanceof SourceNode ) {
chunk . walk ( aFn ) ;
}
else {
if ( chunk !== '' ) {
aFn ( chunk , { source : this . source , line : this . line , column : this . column } ) ;
}
}
} , this ) ;
} ;
/ * *
* Like ` String.prototype.join ` except for SourceNodes . Inserts ` aStr ` between
* each of ` this.children ` .
*
* @ param aSep The separator .
* /
SourceNode . prototype . join = function SourceNode _join ( aSep ) {
var newChildren ;
var i ;
var len = this . children . length
if ( len > 0 ) {
newChildren = [ ] ;
for ( i = 0 ; i < len - 1 ; i ++ ) {
newChildren . push ( this . children [ i ] ) ;
newChildren . push ( aSep ) ;
}
newChildren . push ( this . children [ i ] ) ;
this . children = newChildren ;
}
return this ;
} ;
/ * *
* Call String . prototype . replace on the very right - most source snippet . Useful
* for trimming whitespace from the end of a source node , etc .
*
* @ param aPattern The pattern to replace .
* @ param aReplacement The thing to replace the pattern with .
* /
SourceNode . prototype . replaceRight = function SourceNode _replaceRight ( aPattern , aReplacement ) {
var lastChild = this . children [ this . children . length - 1 ] ;
if ( lastChild instanceof SourceNode ) {
lastChild . replaceRight ( aPattern , aReplacement ) ;
}
else if ( typeof lastChild === 'string' ) {
this . children [ this . children . length - 1 ] = lastChild . replace ( aPattern , aReplacement ) ;
}
else {
this . children . push ( '' . replace ( aPattern , aReplacement ) ) ;
}
return this ;
} ;
/ * *
* Return the string representation of this source node . Walks over the tree
* and concatenates all the various snippets together to one string .
* /
SourceNode . prototype . toString = function SourceNode _toString ( ) {
var str = "" ;
this . walk ( function ( chunk ) {
str += chunk ;
} ) ;
return str ;
} ;
/ * *
* Returns the string representation of this source node along with a source
* map .
* /
SourceNode . prototype . toStringWithSourceMap = function SourceNode _toStringWithSourceMap ( aArgs ) {
var generated = {
code : "" ,
line : 1 ,
column : 0
} ;
var map = new SourceMapGenerator ( aArgs ) ;
this . walk ( function ( chunk , original ) {
generated . code += chunk ;
if ( original . source != null
&& original . line != null
&& original . column != null ) {
map . addMapping ( {
source : original . source ,
original : {
line : original . line ,
column : original . column
} ,
generated : {
line : generated . line ,
column : generated . column
}
} ) ;
}
chunk . split ( '' ) . forEach ( function ( char ) {
if ( char === '\n' ) {
generated . line ++ ;
generated . column = 0 ;
} else {
generated . column ++ ;
}
} ) ;
} ) ;
return { code : generated . code , map : map } ;
} ;
exports . SourceNode = SourceNode ;
} ) ;
2014-01-03 15:54:38 +00:00
} , { "./source-map-generator" : 13 , "amdefine" : 16 } ] , 15 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/* -*- Mode: js; js-indent-level: 2; -*- */
/ *
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license . See LICENSE or :
* http : //opensource.org/licenses/BSD-3-Clause
* /
if ( typeof define !== 'function' ) {
var define = require ( 'amdefine' ) ( module ) ;
}
define ( function ( require , exports , module ) {
/ * *
* This is a helper function for getting values from parameter / options
* objects .
*
* @ param args The object we are extracting values from
* @ param name The name of the property we are getting .
* @ param defaultValue An optional value to return if the property is missing
* from the object . If this is not specified and the property is missing , an
* error will be thrown .
* /
function getArg ( aArgs , aName , aDefaultValue ) {
if ( aName in aArgs ) {
return aArgs [ aName ] ;
} else if ( arguments . length === 3 ) {
return aDefaultValue ;
} else {
throw new Error ( '"' + aName + '" is a required argument.' ) ;
}
}
exports . getArg = getArg ;
function join ( aRoot , aPath ) {
return aPath . charAt ( 0 ) === '/'
? aPath
: aRoot . replace ( /\/*$/ , '' ) + '/' + aPath ;
}
exports . join = join ;
} ) ;
2014-01-03 15:54:38 +00:00
} , { "amdefine" : 16 } ] , 16 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
var process = require ( "__browserify_process" ) , _ _filename = "/../node_modules/jstransform/node_modules/source-map/node_modules/amdefine/amdefine.js" ; / * * v i m : e t : t s = 4 : s w = 4 : s t s = 4
* @ license amdefine 0.1 . 0 Copyright ( c ) 2011 , The Dojo Foundation All Rights Reserved .
* Available via the MIT or new BSD license .
* see : http : //github.com/jrburke/amdefine for details
* /
/*jslint node: true */
/*global module, process */
'use strict' ;
/ * *
* Creates a define for node .
* @ param { Object } module the "module" object that is defined by Node for the
* current module .
* @ param { Function } [ requireFn ] . Node ' s require function for the current module .
* It only needs to be passed in Node versions before 0.5 , when module . require
* did not exist .
* @ returns { Function } a define function that is usable for the current node
* module .
* /
function amdefine ( module , requireFn ) {
'use strict' ;
var defineCache = { } ,
loaderCache = { } ,
alreadyCalled = false ,
path = require ( 'path' ) ,
makeRequire , stringRequire ;
/ * *
* Trims the . and . . from an array of path segments .
* It will keep a leading path segment if a . . will become
* the first path segment , to help with module name lookups ,
* which act like paths , but can be remapped . But the end result ,
* all paths that use this function should look normalized .
* NOTE : this method MODIFIES the input array .
* @ param { Array } ary the array of path segments .
* /
function trimDots ( ary ) {
var i , part ;
for ( i = 0 ; ary [ i ] ; i += 1 ) {
part = ary [ i ] ;
if ( part === '.' ) {
ary . splice ( i , 1 ) ;
i -= 1 ;
} else if ( part === '..' ) {
if ( i === 1 && ( ary [ 2 ] === '..' || ary [ 0 ] === '..' ) ) {
//End of the line. Keep at least one non-dot
//path segment at the front so it can be mapped
//correctly to disk. Otherwise, there is likely
//no path mapping for a path starting with '..'.
//This can still fail, but catches the most reasonable
//uses of ..
break ;
} else if ( i > 0 ) {
ary . splice ( i - 1 , 2 ) ;
i -= 2 ;
}
}
}
}
function normalize ( name , baseName ) {
var baseParts ;
//Adjust any relative paths.
if ( name && name . charAt ( 0 ) === '.' ) {
//If have a base name, try to normalize against it,
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if ( baseName ) {
baseParts = baseName . split ( '/' ) ;
baseParts = baseParts . slice ( 0 , baseParts . length - 1 ) ;
baseParts = baseParts . concat ( name . split ( '/' ) ) ;
trimDots ( baseParts ) ;
name = baseParts . join ( '/' ) ;
}
}
return name ;
}
/ * *
* Create the normalize ( ) function passed to a loader plugin ' s
* normalize method .
* /
function makeNormalize ( relName ) {
return function ( name ) {
return normalize ( name , relName ) ;
} ;
}
function makeLoad ( id ) {
function load ( value ) {
loaderCache [ id ] = value ;
}
load . fromText = function ( id , text ) {
//This one is difficult because the text can/probably uses
//define, and any relative paths and requires should be relative
//to that id was it would be found on disk. But this would require
//bootstrapping a module/require fairly deeply from node core.
//Not sure how best to go about that yet.
throw new Error ( 'amdefine does not implement load.fromText' ) ;
} ;
return load ;
}
makeRequire = function ( systemRequire , exports , module , relId ) {
function amdRequire ( deps , callback ) {
if ( typeof deps === 'string' ) {
//Synchronous, single module require('')
return stringRequire ( systemRequire , exports , module , deps , relId ) ;
} else {
//Array of dependencies with a callback.
//Convert the dependencies to modules.
deps = deps . map ( function ( depName ) {
return stringRequire ( systemRequire , exports , module , depName , relId ) ;
} ) ;
//Wait for next tick to call back the require call.
process . nextTick ( function ( ) {
callback . apply ( null , deps ) ;
} ) ;
}
}
amdRequire . toUrl = function ( filePath ) {
if ( filePath . indexOf ( '.' ) === 0 ) {
return normalize ( filePath , path . dirname ( module . filename ) ) ;
} else {
return filePath ;
}
} ;
return amdRequire ;
} ;
//Favor explicit value, passed in if the module wants to support Node 0.4.
requireFn = requireFn || function req ( ) {
return module . require . apply ( module , arguments ) ;
} ;
function runFactory ( id , deps , factory ) {
var r , e , m , result ;
if ( id ) {
e = loaderCache [ id ] = { } ;
m = {
id : id ,
uri : _ _filename ,
exports : e
} ;
r = makeRequire ( requireFn , e , m , id ) ;
} else {
//Only support one define call per file
if ( alreadyCalled ) {
throw new Error ( 'amdefine with no module ID cannot be called more than once per file.' ) ;
}
alreadyCalled = true ;
//Use the real variables from node
//Use module.exports for exports, since
//the exports in here is amdefine exports.
e = module . exports ;
m = module ;
r = makeRequire ( requireFn , e , m , module . id ) ;
}
//If there are dependencies, they are strings, so need
//to convert them to dependency values.
if ( deps ) {
deps = deps . map ( function ( depName ) {
return r ( depName ) ;
} ) ;
}
//Call the factory with the right dependencies.
if ( typeof factory === 'function' ) {
result = factory . apply ( m . exports , deps ) ;
} else {
result = factory ;
}
if ( result !== undefined ) {
m . exports = result ;
if ( id ) {
loaderCache [ id ] = m . exports ;
}
}
}
stringRequire = function ( systemRequire , exports , module , id , relId ) {
//Split the ID by a ! so that
var index = id . indexOf ( '!' ) ,
originalId = id ,
prefix , plugin ;
if ( index === - 1 ) {
id = normalize ( id , relId ) ;
//Straight module lookup. If it is one of the special dependencies,
//deal with it, otherwise, delegate to node.
if ( id === 'require' ) {
return makeRequire ( systemRequire , exports , module , relId ) ;
} else if ( id === 'exports' ) {
return exports ;
} else if ( id === 'module' ) {
return module ;
} else if ( loaderCache . hasOwnProperty ( id ) ) {
return loaderCache [ id ] ;
} else if ( defineCache [ id ] ) {
runFactory . apply ( null , defineCache [ id ] ) ;
return loaderCache [ id ] ;
} else {
if ( systemRequire ) {
return systemRequire ( originalId ) ;
} else {
throw new Error ( 'No module with ID: ' + id ) ;
}
}
} else {
//There is a plugin in play.
prefix = id . substring ( 0 , index ) ;
id = id . substring ( index + 1 , id . length ) ;
plugin = stringRequire ( systemRequire , exports , module , prefix , relId ) ;
if ( plugin . normalize ) {
id = plugin . normalize ( id , makeNormalize ( relId ) ) ;
} else {
//Normalize the ID normally.
id = normalize ( id , relId ) ;
}
if ( loaderCache [ id ] ) {
return loaderCache [ id ] ;
} else {
plugin . load ( id , makeRequire ( systemRequire , exports , module , relId ) , makeLoad ( id ) , { } ) ;
return loaderCache [ id ] ;
}
}
} ;
//Create a define function specific to the module asking for amdefine.
function define ( id , deps , factory ) {
if ( Array . isArray ( id ) ) {
factory = deps ;
deps = id ;
id = undefined ;
} else if ( typeof id !== 'string' ) {
factory = id ;
id = deps = undefined ;
}
if ( deps && ! Array . isArray ( deps ) ) {
factory = deps ;
deps = undefined ;
}
if ( ! deps ) {
deps = [ 'require' , 'exports' , 'module' ] ;
}
//Set up properties for this module. If an ID, then use
//internal cache. If no ID, then use the external variables
//for this node module.
if ( id ) {
//Put the module in deep freeze until there is a
//require call for it.
defineCache [ id ] = [ id , deps , factory ] ;
} else {
runFactory ( id , deps , factory ) ;
}
}
//define.require, which has access to all the values in the
//cache. Useful for AMD modules that all have IDs in the file,
//but need to finally export a value to node based on one of those
//IDs.
define . require = function ( id ) {
if ( loaderCache [ id ] ) {
return loaderCache [ id ] ;
}
if ( defineCache [ id ] ) {
runFactory . apply ( null , defineCache [ id ] ) ;
return loaderCache [ id ] ;
}
} ;
define . amd = { } ;
return define ;
}
module . exports = amdefine ;
2014-01-03 15:54:38 +00:00
} , { "__browserify_process" : 4 , "path" : 2 } ] , 17 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ * *
* Copyright 2013 Facebook , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
var docblockRe = /^\s*(\/\*\*(.|\r?\n)*?\*\/)/ ;
var ltrimRe = /^\s*/ ;
/ * *
* @ param { String } contents
* @ return { String }
* /
function extract ( contents ) {
var match = contents . match ( docblockRe ) ;
if ( match ) {
return match [ 0 ] . replace ( ltrimRe , '' ) || '' ;
}
return '' ;
}
var commentStartRe = /^\/\*\*?/ ;
var commentEndRe = /\*\/$/ ;
var wsRe = /[\t ]+/g ;
var stringStartRe = /(\r?\n|^) *\*/g ;
var multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *([^@\r\n\s][^@\r\n]+?) *\r?\n/g ;
var propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g ;
/ * *
* @ param { String } contents
* @ return { Array }
* /
function parse ( docblock ) {
docblock = docblock
. replace ( commentStartRe , '' )
. replace ( commentEndRe , '' )
. replace ( wsRe , ' ' )
. replace ( stringStartRe , '$1' ) ;
// Normalize multi-line directives
var prev = '' ;
while ( prev != docblock ) {
prev = docblock ;
docblock = docblock . replace ( multilineRe , "\n$1 $2\n" ) ;
}
docblock = docblock . trim ( ) ;
var result = [ ] ;
var match ;
while ( match = propertyRe . exec ( docblock ) ) {
result . push ( [ match [ 1 ] , match [ 2 ] ] ) ;
}
return result ;
}
/ * *
* Same as parse but returns an object of prop : value instead of array of paris
* If a property appers more than once the last one will be returned
*
* @ param { String } contents
* @ return { Object }
* /
function parseAsObject ( docblock ) {
var pairs = parse ( docblock ) ;
var result = { } ;
for ( var i = 0 ; i < pairs . length ; i ++ ) {
result [ pairs [ i ] [ 0 ] ] = pairs [ i ] [ 1 ] ;
}
return result ;
}
exports . extract = extract ;
exports . parse = parse ;
exports . parseAsObject = parseAsObject ;
2014-01-03 15:54:38 +00:00
} , { } ] , 18 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ * *
* Copyright 2013 Facebook , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/*jslint node: true*/
"use strict" ;
/ * *
* Syntax transfomer for javascript . Takes the source in , spits the source
* out .
*
* Parses input source with esprima , applies the given list of visitors to the
* AST tree , and returns the resulting output .
* /
var esprima = require ( 'esprima-fb' ) ;
var createState = require ( './utils' ) . createState ;
var catchup = require ( './utils' ) . catchup ;
var updateState = require ( './utils' ) . updateState ;
var analyzeAndTraverse = require ( './utils' ) . analyzeAndTraverse ;
var Syntax = esprima . Syntax ;
/ * *
* @ param { object } node
* @ param { object } parentNode
* @ return { boolean }
* /
function _nodeIsClosureScopeBoundary ( node , parentNode ) {
if ( node . type === Syntax . Program ) {
return true ;
}
var parentIsFunction =
parentNode . type === Syntax . FunctionDeclaration
|| parentNode . type === Syntax . FunctionExpression ;
return node . type === Syntax . BlockStatement && parentIsFunction ;
}
function _nodeIsBlockScopeBoundary ( node , parentNode ) {
if ( node . type === Syntax . Program ) {
return false ;
}
return node . type === Syntax . BlockStatement
&& parentNode . type === Syntax . CatchClause ;
}
/ * *
* @ param { object } node
* @ param { function } visitor
* @ param { array } path
* @ param { object } state
* /
function traverse ( node , path , state ) {
// Create a scope stack entry if this is the first node we've encountered in
// its local scope
var parentNode = path [ 0 ] ;
if ( ! Array . isArray ( node ) && state . localScope . parentNode !== parentNode ) {
if ( _nodeIsClosureScopeBoundary ( node , parentNode ) ) {
var scopeIsStrict =
state . scopeIsStrict
|| node . body . length > 0
&& node . body [ 0 ] . type === Syntax . ExpressionStatement
&& node . body [ 0 ] . expression . type === Syntax . Literal
&& node . body [ 0 ] . expression . value === 'use strict' ;
if ( node . type === Syntax . Program ) {
state = updateState ( state , {
scopeIsStrict : scopeIsStrict
} ) ;
} else {
state = updateState ( state , {
localScope : {
parentNode : parentNode ,
parentScope : state . localScope ,
identifiers : { }
} ,
scopeIsStrict : scopeIsStrict
} ) ;
// All functions have an implicit 'arguments' object in scope
state . localScope . identifiers [ 'arguments' ] = true ;
// Include function arg identifiers in the scope boundaries of the
// function
if ( parentNode . params . length > 0 ) {
var param ;
for ( var i = 0 ; i < parentNode . params . length ; i ++ ) {
param = parentNode . params [ i ] ;
if ( param . type === Syntax . Identifier ) {
state . localScope . identifiers [ param . name ] = true ;
}
}
}
// Named FunctionExpressions scope their name within the body block of
// themselves only
if ( parentNode . type === Syntax . FunctionExpression && parentNode . id ) {
state . localScope . identifiers [ parentNode . id . name ] = true ;
}
}
// Traverse and find all local identifiers in this closure first to
// account for function/variable declaration hoisting
collectClosureIdentsAndTraverse ( node , path , state ) ;
}
if ( _nodeIsBlockScopeBoundary ( node , parentNode ) ) {
state = updateState ( state , {
localScope : {
parentNode : parentNode ,
parentScope : state . localScope ,
identifiers : { }
}
} ) ;
if ( parentNode . type === Syntax . CatchClause ) {
state . localScope . identifiers [ parentNode . param . name ] = true ;
}
collectBlockIdentsAndTraverse ( node , path , state ) ;
}
}
// Only catchup() before and after traversing a child node
function traverser ( node , path , state ) {
node . range && catchup ( node . range [ 0 ] , state ) ;
traverse ( node , path , state ) ;
node . range && catchup ( node . range [ 1 ] , state ) ;
}
analyzeAndTraverse ( walker , traverser , node , path , state ) ;
}
function collectClosureIdentsAndTraverse ( node , path , state ) {
analyzeAndTraverse (
visitLocalClosureIdentifiers ,
collectClosureIdentsAndTraverse ,
node ,
path ,
state
) ;
}
function collectBlockIdentsAndTraverse ( node , path , state ) {
analyzeAndTraverse (
visitLocalBlockIdentifiers ,
collectBlockIdentsAndTraverse ,
node ,
path ,
state
) ;
}
function visitLocalClosureIdentifiers ( node , path , state ) {
var identifiers = state . localScope . identifiers ;
switch ( node . type ) {
case Syntax . FunctionExpression :
// Function expressions don't get their names (if there is one) added to
// the closure scope they're defined in
return false ;
case Syntax . ClassDeclaration :
case Syntax . ClassExpression :
case Syntax . FunctionDeclaration :
if ( node . id ) {
identifiers [ node . id . name ] = true ;
}
return false ;
case Syntax . VariableDeclarator :
if ( path [ 0 ] . kind === 'var' ) {
identifiers [ node . id . name ] = true ;
}
break ;
}
}
function visitLocalBlockIdentifiers ( node , path , state ) {
// TODO: Support 'let' here...maybe...one day...or something...
if ( node . type === Syntax . CatchClause ) {
return false ;
}
}
function walker ( node , path , state ) {
var visitors = state . g . visitors ;
for ( var i = 0 ; i < visitors . length ; i ++ ) {
if ( visitors [ i ] . test ( node , path , state ) ) {
return visitors [ i ] ( traverse , node , path , state ) ;
}
}
}
/ * *
* Applies all available transformations to the source
* @ param { array } visitors
* @ param { string } source
* @ param { ? object } options
* @ return { object }
* /
function transform ( visitors , source , options ) {
options = options || { } ;
var ast ;
try {
ast = esprima . parse ( source , {
comment : true ,
loc : true ,
range : true
} ) ;
} catch ( e ) {
e . message = 'Parse Error: ' + e . message ;
throw e ;
}
var state = createState ( source , ast , options ) ;
state . g . visitors = visitors ;
if ( options . sourceMap ) {
var SourceMapGenerator = require ( 'source-map' ) . SourceMapGenerator ;
state . g . sourceMap = new SourceMapGenerator ( { file : 'transformed.js' } ) ;
}
traverse ( ast , [ ] , state ) ;
catchup ( source . length , state ) ;
var ret = { code : state . g . buffer } ;
if ( options . sourceMap ) {
ret . sourceMap = state . g . sourceMap ;
ret . sourceMapFilename = options . filename || 'source.js' ;
}
return ret ;
}
exports . transform = transform ;
2014-01-03 15:54:38 +00:00
} , { "./utils" : 19 , "esprima-fb" : 5 , "source-map" : 7 } ] , 19 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ * *
* Copyright 2013 Facebook , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/*jslint node: true*/
/ * *
* A ` state ` object represents the state of the parser . It has "local" and
* "global" parts . Global contains parser position , source , etc . Local contains
* scope based properties like current class name . State should contain all the
* info required for transformation . It ' s the only mandatory object that is
* being passed to every function in transform chain .
*
* @ param { string } source
* @ param { object } transformOptions
* @ return { object }
* /
function createState ( source , rootNode , transformOptions ) {
return {
/ * *
* A tree representing the current local scope ( and its lexical scope chain )
* Useful for tracking identifiers from parent scopes , etc .
* @ type { Object }
* /
localScope : {
parentNode : rootNode ,
parentScope : null ,
identifiers : { }
} ,
/ * *
* The name ( and , if applicable , expression ) of the super class
* @ type { Object }
* /
superClass : null ,
/ * *
* The namespace to use when munging identifiers
* @ type { String }
* /
mungeNamespace : '' ,
/ * *
* Ref to the node for the FunctionExpression of the enclosing
* MethodDefinition
* @ type { Object }
* /
methodFuncNode : null ,
/ * *
* Name of the enclosing class
* @ type { String }
* /
className : null ,
/ * *
* Whether we ' re currently within a ` strict ` scope
* @ type { Bool }
* /
scopeIsStrict : null ,
/ * *
* Global state ( not affected by updateState )
* @ type { Object }
* /
g : {
/ * *
* A set of general options that transformations can consider while doing
* a transformation :
*
* - minify
* Specifies that transformation steps should do their best to minify
* the output source when possible . This is useful for places where
* minification optimizations are possible with higher - level context
* info than what jsxmin can provide .
*
* For example , the ES6 class transform will minify munged private
* variables if this flag is set .
* /
opts : transformOptions ,
/ * *
* Current position in the source code
* @ type { Number }
* /
position : 0 ,
/ * *
* Buffer containing the result
* @ type { String }
* /
buffer : '' ,
/ * *
* Indentation offset ( only negative offset is supported now )
* @ type { Number }
* /
indentBy : 0 ,
/ * *
* Source that is being transformed
* @ type { String }
* /
source : source ,
/ * *
* Cached parsed docblock ( see getDocblock )
* @ type { object }
* /
docblock : null ,
/ * *
* Whether the thing was used
* @ type { Boolean }
* /
tagNamespaceUsed : false ,
/ * *
* If using bolt xjs transformation
* @ type { Boolean }
* /
isBolt : undefined ,
/ * *
* Whether to record source map ( expensive ) or not
* @ type { SourceMapGenerator | null }
* /
sourceMap : null ,
/ * *
* Filename of the file being processed . Will be returned as a source
* attribute in the source map
* /
sourceMapFilename : 'source.js' ,
/ * *
* Only when source map is used : last line in the source for which
* source map was generated
* @ type { Number }
* /
sourceLine : 1 ,
/ * *
* Only when source map is used : last line in the buffer for which
* source map was generated
* @ type { Number }
* /
bufferLine : 1 ,
/ * *
* The top - level Program AST for the original file .
* /
originalProgramAST : null ,
sourceColumn : 0 ,
bufferColumn : 0
}
} ;
}
/ * *
* Updates a copy of a given state with "update" and returns an updated state .
*
* @ param { object } state
* @ param { object } update
* @ return { object }
* /
function updateState ( state , update ) {
var ret = Object . create ( state ) ;
Object . keys ( update ) . forEach ( function ( updatedKey ) {
ret [ updatedKey ] = update [ updatedKey ] ;
} ) ;
return ret ;
}
/ * *
* Given a state fill the resulting buffer from the original source up to
* the end
*
* @ param { number } end
* @ param { object } state
* @ param { ? function } contentTransformer Optional callback to transform newly
* added content .
* /
function catchup ( end , state , contentTransformer ) {
if ( end < state . g . position ) {
// cannot move backwards
return ;
}
var source = state . g . source . substring ( state . g . position , end ) ;
var transformed = updateIndent ( source , state ) ;
if ( state . g . sourceMap && transformed ) {
// record where we are
state . g . sourceMap . addMapping ( {
generated : { line : state . g . bufferLine , column : state . g . bufferColumn } ,
original : { line : state . g . sourceLine , column : state . g . sourceColumn } ,
source : state . g . sourceMapFilename
} ) ;
// record line breaks in transformed source
var sourceLines = source . split ( '\n' ) ;
var transformedLines = transformed . split ( '\n' ) ;
// Add line break mappings between last known mapping and the end of the
// added piece. So for the code piece
// (foo, bar);
// > var x = 2;
// > var b = 3;
// var c =
// only add lines marked with ">": 2, 3.
for ( var i = 1 ; i < sourceLines . length - 1 ; i ++ ) {
state . g . sourceMap . addMapping ( {
generated : { line : state . g . bufferLine , column : 0 } ,
original : { line : state . g . sourceLine , column : 0 } ,
source : state . g . sourceMapFilename
} ) ;
state . g . sourceLine ++ ;
state . g . bufferLine ++ ;
}
// offset for the last piece
if ( sourceLines . length > 1 ) {
state . g . sourceLine ++ ;
state . g . bufferLine ++ ;
state . g . sourceColumn = 0 ;
state . g . bufferColumn = 0 ;
}
state . g . sourceColumn += sourceLines [ sourceLines . length - 1 ] . length ;
state . g . bufferColumn +=
transformedLines [ transformedLines . length - 1 ] . length ;
}
state . g . buffer +=
contentTransformer ? contentTransformer ( transformed ) : transformed ;
state . g . position = end ;
}
/ * *
* Removes all non - whitespace characters
* /
var reNonWhite = /(\S)/g ;
function stripNonWhite ( value ) {
return value . replace ( reNonWhite , function ( ) {
return '' ;
} ) ;
}
/ * *
* Catches up as ` catchup ` but removes all non - whitespace characters .
* /
function catchupWhiteSpace ( end , state ) {
catchup ( end , state , stripNonWhite ) ;
}
/ * *
* Removes all non - newline characters
* /
var reNonNewline = /[^\n]/g ;
function stripNonNewline ( value ) {
return value . replace ( reNonNewline , function ( ) {
return '' ;
} ) ;
}
/ * *
* Catches up as ` catchup ` but removes all non - newline characters .
*
* Equivalent to appending as many newlines as there are in the original source
* between the current position and ` end ` .
* /
function catchupNewlines ( end , state ) {
catchup ( end , state , stripNonNewline ) ;
}
/ * *
* Same as catchup but does not touch the buffer
*
* @ param { number } end
* @ param { object } state
* /
function move ( end , state ) {
// move the internal cursors
if ( state . g . sourceMap ) {
if ( end < state . g . position ) {
state . g . position = 0 ;
state . g . sourceLine = 1 ;
state . g . sourceColumn = 0 ;
}
var source = state . g . source . substring ( state . g . position , end ) ;
var sourceLines = source . split ( '\n' ) ;
if ( sourceLines . length > 1 ) {
state . g . sourceLine += sourceLines . length - 1 ;
state . g . sourceColumn = 0 ;
}
state . g . sourceColumn += sourceLines [ sourceLines . length - 1 ] . length ;
}
state . g . position = end ;
}
/ * *
* Appends a string of text to the buffer
*
* @ param { string } str
* @ param { object } state
* /
function append ( str , state ) {
if ( state . g . sourceMap && str ) {
state . g . sourceMap . addMapping ( {
generated : { line : state . g . bufferLine , column : state . g . bufferColumn } ,
original : { line : state . g . sourceLine , column : state . g . sourceColumn } ,
source : state . g . sourceMapFilename
} ) ;
var transformedLines = str . split ( '\n' ) ;
if ( transformedLines . length > 1 ) {
state . g . bufferLine += transformedLines . length - 1 ;
state . g . bufferColumn = 0 ;
}
state . g . bufferColumn +=
transformedLines [ transformedLines . length - 1 ] . length ;
}
state . g . buffer += str ;
}
/ * *
* Update indent using state . indentBy property . Indent is measured in
* double spaces . Updates a single line only .
*
* @ param { string } str
* @ param { object } state
* @ return { string }
* /
function updateIndent ( str , state ) {
for ( var i = 0 ; i < - state . g . indentBy ; i ++ ) {
str = str . replace ( /(^|\n)( {2}|\t)/g , '$1' ) ;
}
return str ;
}
/ * *
* Calculates indent from the beginning of the line until "start" or the first
* character before start .
* @ example
* " foo.bar()"
* ^
* start
* indent will be 2
*
* @ param { number } start
* @ param { object } state
* @ return { number }
* /
function indentBefore ( start , state ) {
var end = start ;
start = start - 1 ;
while ( start > 0 && state . g . source [ start ] != '\n' ) {
if ( ! state . g . source [ start ] . match ( /[ \t]/ ) ) {
end = start ;
}
start -- ;
}
return state . g . source . substring ( start + 1 , end ) ;
}
function getDocblock ( state ) {
if ( ! state . g . docblock ) {
var docblock = require ( './docblock' ) ;
state . g . docblock =
docblock . parseAsObject ( docblock . extract ( state . g . source ) ) ;
}
return state . g . docblock ;
}
function identWithinLexicalScope ( identName , state , stopBeforeNode ) {
var currScope = state . localScope ;
while ( currScope ) {
if ( currScope . identifiers [ identName ] !== undefined ) {
return true ;
}
if ( stopBeforeNode && currScope . parentNode === stopBeforeNode ) {
break ;
}
currScope = currScope . parentScope ;
}
return false ;
}
function identInLocalScope ( identName , state ) {
return state . localScope . identifiers [ identName ] !== undefined ;
}
function declareIdentInLocalScope ( identName , state ) {
state . localScope . identifiers [ identName ] = true ;
}
/ * *
* Apply the given analyzer function to the current node . If the analyzer
* doesn ' t return false , traverse each child of the current node using the given
* traverser function .
*
* @ param { function } analyzer
* @ param { function } traverser
* @ param { object } node
* @ param { function } visitor
* @ param { array } path
* @ param { object } state
* /
function analyzeAndTraverse ( analyzer , traverser , node , path , state ) {
var key , child ;
if ( node . type ) {
if ( analyzer ( node , path , state ) === false ) {
return ;
}
path . unshift ( node ) ;
}
for ( key in node ) {
// skip obviously wrong attributes
if ( key === 'range' || key === 'loc' ) {
continue ;
}
if ( node . hasOwnProperty ( key ) ) {
child = node [ key ] ;
if ( typeof child === 'object' && child !== null ) {
traverser ( child , path , state ) ;
}
}
}
node . type && path . shift ( ) ;
}
/ * *
* Checks whether a node or any of its sub - nodes contains
* a syntactic construct of the passed type .
* @ param { object } node - AST node to test .
* @ param { string } type - node type to lookup .
* /
function containsChildOfType ( node , type ) {
var foundMatchingChild = false ;
function nodeTypeAnalyzer ( node ) {
if ( node . type === type ) {
foundMatchingChild = true ;
return false ;
}
}
function nodeTypeTraverser ( child , path , state ) {
if ( ! foundMatchingChild ) {
foundMatchingChild = containsChildOfType ( child , type ) ;
}
}
analyzeAndTraverse (
nodeTypeAnalyzer ,
nodeTypeTraverser ,
node ,
[ ]
) ;
return foundMatchingChild ;
}
exports . append = append ;
exports . catchup = catchup ;
exports . catchupWhiteSpace = catchupWhiteSpace ;
exports . catchupNewlines = catchupNewlines ;
exports . containsChildOfType = containsChildOfType ;
exports . createState = createState ;
exports . declareIdentInLocalScope = declareIdentInLocalScope ;
exports . getDocblock = getDocblock ;
exports . identWithinLexicalScope = identWithinLexicalScope ;
exports . identInLocalScope = identInLocalScope ;
exports . indentBefore = indentBefore ;
exports . move = move ;
exports . updateIndent = updateIndent ;
exports . updateState = updateState ;
exports . analyzeAndTraverse = analyzeAndTraverse ;
2014-01-03 15:54:38 +00:00
} , { "./docblock" : 17 } ] , 20 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ * *
* Copyright 2013 Facebook , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/*jslint node:true*/
/ * *
* @ typechecks
* /
'use strict' ;
var base62 = require ( 'base62' ) ;
var Syntax = require ( 'esprima-fb' ) . Syntax ;
var utils = require ( '../src/utils' ) ;
var SUPER _PROTO _IDENT _PREFIX = '____SuperProtoOf' ;
var _anonClassUUIDCounter = 0 ;
var _mungedSymbolMaps = { } ;
/ * *
* Used to generate a unique class for use with code - gens for anonymous class
* expressions .
*
* @ param { object } state
* @ return { string }
* /
function _generateAnonymousClassName ( state ) {
var mungeNamespace = state . mungeNamespace || '' ;
return '____Class' + mungeNamespace + base62 . encode ( _anonClassUUIDCounter ++ ) ;
}
/ * *
* Given an identifier name , munge it using the current state ' s mungeNamespace .
*
* @ param { string } identName
* @ param { object } state
* @ return { string }
* /
function _getMungedName ( identName , state ) {
var mungeNamespace = state . mungeNamespace ;
var shouldMinify = state . g . opts . minify ;
if ( shouldMinify ) {
if ( ! _mungedSymbolMaps [ mungeNamespace ] ) {
_mungedSymbolMaps [ mungeNamespace ] = {
symbolMap : { } ,
identUUIDCounter : 0
} ;
}
var symbolMap = _mungedSymbolMaps [ mungeNamespace ] . symbolMap ;
if ( ! symbolMap [ identName ] ) {
symbolMap [ identName ] =
base62 . encode ( _mungedSymbolMaps [ mungeNamespace ] . identUUIDCounter ++ ) ;
}
identName = symbolMap [ identName ] ;
}
return '$' + mungeNamespace + identName ;
}
/ * *
* Extracts super class information from a class node .
*
* Information includes name of the super class and / or the expression string
* ( if extending from an expression )
*
* @ param { object } node
* @ param { object } state
* @ return { object }
* /
function _getSuperClassInfo ( node , state ) {
var ret = {
name : null ,
expression : null
} ;
if ( node . superClass ) {
if ( node . superClass . type === Syntax . Identifier ) {
ret . name = node . superClass . name ;
} else {
// Extension from an expression
ret . name = _generateAnonymousClassName ( state ) ;
ret . expression = state . g . source . substring (
node . superClass . range [ 0 ] ,
node . superClass . range [ 1 ]
) ;
}
}
return ret ;
}
/ * *
* Used with . filter ( ) to find the constructor method in a list of
* MethodDefinition nodes .
*
* @ param { object } classElement
* @ return { boolean }
* /
function _isConstructorMethod ( classElement ) {
return classElement . type === Syntax . MethodDefinition &&
classElement . key . type === Syntax . Identifier &&
classElement . key . name === 'constructor' ;
}
/ * *
* @ param { object } node
* @ param { object } state
* @ return { boolean }
* /
function _shouldMungeIdentifier ( node , state ) {
return (
! ! state . methodFuncNode &&
! utils . getDocblock ( state ) . hasOwnProperty ( 'preventMunge' ) &&
/^_(?!_)/ . test ( node . name )
) ;
}
/ * *
* @ param { function } traverse
* @ param { object } node
* @ param { array } path
* @ param { object } state
* /
function visitClassMethod ( traverse , node , path , state ) {
utils . catchup ( node . range [ 0 ] , state ) ;
path . unshift ( node ) ;
traverse ( node . value , path , state ) ;
path . shift ( ) ;
return false ;
}
visitClassMethod . test = function ( node , path , state ) {
return node . type === Syntax . MethodDefinition ;
} ;
/ * *
* @ param { function } traverse
* @ param { object } node
* @ param { array } path
* @ param { object } state
* /
function visitClassFunctionExpression ( traverse , node , path , state ) {
var methodNode = path [ 0 ] ;
state = utils . updateState ( state , {
methodFuncNode : node
} ) ;
if ( methodNode . key . name === 'constructor' ) {
utils . append ( 'function ' + state . className , state ) ;
} else {
var methodName = methodNode . key . name ;
if ( _shouldMungeIdentifier ( methodNode . key , state ) ) {
methodName = _getMungedName ( methodName , state ) ;
}
var prototypeOrStatic = methodNode . static ? '' : 'prototype.' ;
utils . append (
state . className + '.' + prototypeOrStatic + methodName + '=function' ,
state
) ;
}
utils . move ( methodNode . key . range [ 1 ] , state ) ;
var params = node . params ;
var paramName ;
if ( params . length > 0 ) {
for ( var i = 0 ; i < params . length ; i ++ ) {
utils . catchup ( node . params [ i ] . range [ 0 ] , state ) ;
paramName = params [ i ] . name ;
if ( _shouldMungeIdentifier ( params [ i ] , state ) ) {
paramName = _getMungedName ( params [ i ] . name , state ) ;
}
utils . append ( paramName , state ) ;
utils . move ( params [ i ] . range [ 1 ] , state ) ;
}
} else {
utils . append ( '(' , state ) ;
}
utils . append ( ')' , state ) ;
utils . catchupWhiteSpace ( node . body . range [ 0 ] , state ) ;
utils . append ( '{' , state ) ;
if ( ! state . scopeIsStrict ) {
utils . append ( '"use strict";' , state ) ;
}
utils . move ( node . body . range [ 0 ] + '{' . length , state ) ;
path . unshift ( node ) ;
traverse ( node . body , path , state ) ;
path . shift ( ) ;
utils . catchup ( node . body . range [ 1 ] , state ) ;
if ( methodNode . key . name !== 'constructor' ) {
utils . append ( ';' , state ) ;
}
return false ;
}
visitClassFunctionExpression . test = function ( node , path , state ) {
return node . type === Syntax . FunctionExpression
&& path [ 0 ] . type === Syntax . MethodDefinition ;
} ;
/ * *
* @ param { function } traverse
* @ param { object } node
* @ param { array } path
* @ param { object } state
* /
function _renderClassBody ( traverse , node , path , state ) {
var className = state . className ;
var superClass = state . superClass ;
// Set up prototype of constructor on same line as `extends` for line-number
// preservation. This relies on function-hoisting if a constructor function is
// defined in the class body.
if ( superClass . name ) {
// If the super class is an expression, we need to memoize the output of the
// expression into the generated class name variable and use that to refer
// to the super class going forward. Example:
//
// class Foo extends mixin(Bar, Baz) {}
// --transforms to--
// function Foo() {} var ____Class0Blah = mixin(Bar, Baz);
if ( superClass . expression !== null ) {
utils . append (
'var ' + superClass . name + '=' + superClass . expression + ';' ,
state
) ;
}
var keyName = superClass . name + '____Key' ;
var keyNameDeclarator = '' ;
if ( ! utils . identWithinLexicalScope ( keyName , state ) ) {
keyNameDeclarator = 'var ' ;
utils . declareIdentInLocalScope ( keyName , state ) ;
}
utils . append (
'for(' + keyNameDeclarator + keyName + ' in ' + superClass . name + '){' +
'if(' + superClass . name + '.hasOwnProperty(' + keyName + ')){' +
className + '[' + keyName + ']=' +
superClass . name + '[' + keyName + '];' +
'}' +
'}' ,
state
) ;
var superProtoIdentStr = SUPER _PROTO _IDENT _PREFIX + superClass . name ;
if ( ! utils . identWithinLexicalScope ( superProtoIdentStr , state ) ) {
utils . append (
'var ' + superProtoIdentStr + '=' + superClass . name + '===null?' +
'null:' + superClass . name + '.prototype;' ,
state
) ;
utils . declareIdentInLocalScope ( superProtoIdentStr , state ) ;
}
utils . append (
className + '.prototype=Object.create(' + superProtoIdentStr + ');' ,
state
) ;
utils . append (
className + '.prototype.constructor=' + className + ';' ,
state
) ;
utils . append (
className + '.__superConstructor__=' + superClass . name + ';' ,
state
) ;
}
// If there's no constructor method specified in the class body, create an
// empty constructor function at the top (same line as the class keyword)
if ( ! node . body . body . filter ( _isConstructorMethod ) . pop ( ) ) {
utils . append ( 'function ' + className + '(){' , state ) ;
if ( ! state . scopeIsStrict ) {
utils . append ( '"use strict";' , state ) ;
}
if ( superClass . name ) {
utils . append (
'if(' + superClass . name + '!==null){' +
superClass . name + '.apply(this,arguments);}' ,
state
) ;
}
utils . append ( '}' , state ) ;
}
utils . move ( node . body . range [ 0 ] + '{' . length , state ) ;
traverse ( node . body , path , state ) ;
utils . catchupWhiteSpace ( node . range [ 1 ] , state ) ;
}
/ * *
* @ param { function } traverse
* @ param { object } node
* @ param { array } path
* @ param { object } state
* /
function visitClassDeclaration ( traverse , node , path , state ) {
var className = node . id . name ;
var superClass = _getSuperClassInfo ( node , state ) ;
state = utils . updateState ( state , {
mungeNamespace : className ,
className : className ,
superClass : superClass
} ) ;
_renderClassBody ( traverse , node , path , state ) ;
return false ;
}
visitClassDeclaration . test = function ( node , path , state ) {
return node . type === Syntax . ClassDeclaration ;
} ;
/ * *
* @ param { function } traverse
* @ param { object } node
* @ param { array } path
* @ param { object } state
* /
function visitClassExpression ( traverse , node , path , state ) {
var className = node . id && node . id . name || _generateAnonymousClassName ( state ) ;
var superClass = _getSuperClassInfo ( node , state ) ;
utils . append ( '(function(){' , state ) ;
state = utils . updateState ( state , {
mungeNamespace : className ,
className : className ,
superClass : superClass
} ) ;
_renderClassBody ( traverse , node , path , state ) ;
utils . append ( 'return ' + className + ';})()' , state ) ;
return false ;
}
visitClassExpression . test = function ( node , path , state ) {
return node . type === Syntax . ClassExpression ;
} ;
/ * *
* @ param { function } traverse
* @ param { object } node
* @ param { array } path
* @ param { object } state
* /
function visitPrivateIdentifier ( traverse , node , path , state ) {
utils . append ( _getMungedName ( node . name , state ) , state ) ;
utils . move ( node . range [ 1 ] , state ) ;
}
visitPrivateIdentifier . test = function ( node , path , state ) {
if ( node . type === Syntax . Identifier && _shouldMungeIdentifier ( node , state ) ) {
// Always munge non-computed properties of MemberExpressions
// (a la preventing access of properties of unowned objects)
if ( path [ 0 ] . type === Syntax . MemberExpression && path [ 0 ] . object !== node
&& path [ 0 ] . computed === false ) {
return true ;
}
// Always munge identifiers that were declared within the method function
// scope
if ( utils . identWithinLexicalScope ( node . name , state , state . methodFuncNode ) ) {
return true ;
}
// Always munge private keys on object literals defined within a method's
// scope.
if ( path [ 0 ] . type === Syntax . Property
&& path [ 1 ] . type === Syntax . ObjectExpression ) {
return true ;
}
// Always munge function parameters
if ( path [ 0 ] . type === Syntax . FunctionExpression
|| path [ 0 ] . type === Syntax . FunctionDeclaration ) {
for ( var i = 0 ; i < path [ 0 ] . params . length ; i ++ ) {
if ( path [ 0 ] . params [ i ] === node ) {
return true ;
}
}
}
}
return false ;
} ;
/ * *
* @ param { function } traverse
* @ param { object } node
* @ param { array } path
* @ param { object } state
* /
function visitSuperCallExpression ( traverse , node , path , state ) {
var superClassName = state . superClass . name ;
if ( node . callee . type === Syntax . Identifier ) {
utils . append ( superClassName + '.call(' , state ) ;
utils . move ( node . callee . range [ 1 ] , state ) ;
} else if ( node . callee . type === Syntax . MemberExpression ) {
utils . append ( SUPER _PROTO _IDENT _PREFIX + superClassName , state ) ;
utils . move ( node . callee . object . range [ 1 ] , state ) ;
if ( node . callee . computed ) {
// ["a" + "b"]
utils . catchup ( node . callee . property . range [ 1 ] + ']' . length , state ) ;
} else {
// .ab
utils . append ( '.' + node . callee . property . name , state ) ;
}
utils . append ( '.call(' , state ) ;
utils . move ( node . callee . range [ 1 ] , state ) ;
}
utils . append ( 'this' , state ) ;
if ( node . arguments . length > 0 ) {
utils . append ( ',' , state ) ;
utils . catchupWhiteSpace ( node . arguments [ 0 ] . range [ 0 ] , state ) ;
traverse ( node . arguments , path , state ) ;
}
utils . catchupWhiteSpace ( node . range [ 1 ] , state ) ;
utils . append ( ')' , state ) ;
return false ;
}
visitSuperCallExpression . test = function ( node , path , state ) {
if ( state . superClass && node . type === Syntax . CallExpression ) {
var callee = node . callee ;
if ( callee . type === Syntax . Identifier && callee . name === 'super'
|| callee . type == Syntax . MemberExpression
&& callee . object . name === 'super' ) {
return true ;
}
}
return false ;
} ;
/ * *
* @ param { function } traverse
* @ param { object } node
* @ param { array } path
* @ param { object } state
* /
function visitSuperMemberExpression ( traverse , node , path , state ) {
var superClassName = state . superClass . name ;
utils . append ( SUPER _PROTO _IDENT _PREFIX + superClassName , state ) ;
utils . move ( node . object . range [ 1 ] , state ) ;
}
visitSuperMemberExpression . test = function ( node , path , state ) {
return state . superClass
&& node . type === Syntax . MemberExpression
&& node . object . type === Syntax . Identifier
&& node . object . name === 'super' ;
} ;
exports . visitorList = [
visitClassDeclaration ,
visitClassExpression ,
visitClassFunctionExpression ,
visitClassMethod ,
visitPrivateIdentifier ,
visitSuperCallExpression ,
visitSuperMemberExpression
] ;
2014-01-03 15:54:38 +00:00
} , { "../src/utils" : 19 , "base62" : 6 , "esprima-fb" : 5 } ] , 21 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ * *
* Copyright 2013 Facebook , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/* jshint browser: true */
/* jslint evil: true */
'use strict' ;
var runScripts ;
var headEl ;
var transform = require ( 'jstransform' ) . transform ;
var visitors = require ( './fbtransform/visitors' ) . transformVisitors ;
var transform = transform . bind ( null , visitors . react ) ;
var docblock = require ( 'jstransform/src/docblock' ) ;
exports . transform = transform ;
exports . exec = function ( code ) {
return eval ( transform ( code ) . code ) ;
} ;
if ( typeof window === "undefined" || window === null ) {
return ;
}
headEl = document . getElementsByTagName ( 'head' ) [ 0 ] ;
var run = exports . run = function ( code ) {
var jsx = docblock . parseAsObject ( docblock . extract ( code ) ) . jsx ;
var functionBody = jsx ? transform ( code ) . code : code ;
var scriptEl = document . createElement ( 'script' ) ;
2014-01-03 15:54:38 +00:00
scriptEl . text = functionBody ;
2013-12-16 22:19:36 +00:00
headEl . appendChild ( scriptEl ) ;
} ;
var load = exports . load = function ( url , callback ) {
var xhr ;
xhr = window . ActiveXObject ? new window . ActiveXObject ( 'Microsoft.XMLHTTP' )
: new XMLHttpRequest ( ) ;
// Disable async since we need to execute scripts in the order they are in the
// DOM to mirror normal script loading.
xhr . open ( 'GET' , url , false ) ;
if ( 'overrideMimeType' in xhr ) {
xhr . overrideMimeType ( 'text/plain' ) ;
}
xhr . onreadystatechange = function ( ) {
if ( xhr . readyState === 4 ) {
if ( xhr . status === 0 || xhr . status === 200 ) {
run ( xhr . responseText ) ;
} else {
throw new Error ( "Could not load " + url ) ;
}
if ( callback ) {
return callback ( ) ;
}
}
} ;
return xhr . send ( null ) ;
} ;
runScripts = function ( ) {
var scripts = document . getElementsByTagName ( 'script' ) ;
2014-01-03 15:54:38 +00:00
// Array.prototype.slice cannot be used on NodeList on IE8
var jsxScripts = [ ] ;
for ( var i = 0 ; i < scripts . length ; i ++ ) {
if ( scripts . item ( i ) . type === 'text/jsx' ) {
jsxScripts . push ( scripts . item ( i ) ) ;
}
}
2013-12-16 22:19:36 +00:00
console . warn ( "You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx" ) ;
jsxScripts . forEach ( function ( script ) {
if ( script . src ) {
load ( script . src ) ;
} else {
run ( script . innerHTML ) ;
}
} ) ;
} ;
if ( window . addEventListener ) {
window . addEventListener ( 'DOMContentLoaded' , runScripts , false ) ;
} else {
window . attachEvent ( 'onload' , runScripts ) ;
}
2014-01-03 15:54:38 +00:00
} , { "./fbtransform/visitors" : 25 , "jstransform" : 18 , "jstransform/src/docblock" : 17 } ] , 22 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ * *
* Copyright 2013 Facebook , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/*global exports:true*/
"use strict" ;
var Syntax = require ( 'esprima-fb' ) . Syntax ;
2014-01-03 15:54:38 +00:00
var utils = require ( 'jstransform/src/utils' ) ;
2013-12-16 22:19:36 +00:00
var FALLBACK _TAGS = require ( './xjs' ) . knownTags ;
var renderXJSExpressionContainer =
require ( './xjs' ) . renderXJSExpressionContainer ;
var renderXJSLiteral = require ( './xjs' ) . renderXJSLiteral ;
var quoteAttrName = require ( './xjs' ) . quoteAttrName ;
/ * *
* Customized desugar processor .
*
* Currently : ( Somewhat tailored to React )
* < X > < / X > = > X ( n u l l , n u l l )
* < X prop = "1" / > => X ( { prop : '1' } , null )
* < X prop = "2" > < Y / > < / X > = > X ( { p r o p : ' 2 ' } , Y ( n u l l , n u l l ) )
* < X prop = "2" > < Y / > < Z / > < / X > = > X ( { p r o p : ' 2 ' } , [ Y ( n u l l , n u l l ) , Z ( n u l l , n u l l ) ] )
*
* Exceptions to the simple rules above :
* if a property is named "class" it will be changed to "className" in the
* javascript since "class" is not a valid object key in javascript .
* /
var JSX _ATTRIBUTE _TRANSFORMS = {
cxName : function ( attr ) {
if ( attr . value . type !== Syntax . Literal ) {
throw new Error ( "cx only accepts a string literal" ) ;
} else {
var classNames = attr . value . value . split ( /\s+/g ) ;
return 'cx(' + classNames . map ( JSON . stringify ) . join ( ',' ) + ')' ;
}
}
} ;
function visitReactTag ( traverse , object , path , state ) {
2014-01-03 15:54:38 +00:00
var jsxObjIdent = utils . getDocblock ( state ) . jsx ;
2013-12-16 22:19:36 +00:00
2014-01-03 15:54:38 +00:00
utils . catchup ( object . openingElement . range [ 0 ] , state ) ;
2013-12-16 22:19:36 +00:00
if ( object . name . namespace ) {
throw new Error (
'Namespace tags are not supported. ReactJSX is not XML.' ) ;
}
var isFallbackTag = FALLBACK _TAGS [ object . name . name ] ;
2014-01-03 15:54:38 +00:00
utils . append (
2013-12-16 22:19:36 +00:00
( isFallbackTag ? jsxObjIdent + '.' : '' ) + ( object . name . name ) + '(' ,
state
) ;
2014-01-03 15:54:38 +00:00
utils . move ( object . name . range [ 1 ] , state ) ;
2013-12-16 22:19:36 +00:00
var childrenToRender = object . children . filter ( function ( child ) {
return ! ( child . type === Syntax . Literal && ! child . value . match ( /\S/ ) ) ;
} ) ;
// if we don't have any attributes, pass in null
if ( object . attributes . length === 0 ) {
2014-01-03 15:54:38 +00:00
utils . append ( 'null' , state ) ;
2013-12-16 22:19:36 +00:00
}
// write attributes
object . attributes . forEach ( function ( attr , index ) {
2014-01-03 15:54:38 +00:00
utils . catchup ( attr . range [ 0 ] , state ) ;
2013-12-16 22:19:36 +00:00
if ( attr . name . namespace ) {
throw new Error (
'Namespace attributes are not supported. ReactJSX is not XML.' ) ;
}
var name = attr . name . name ;
var isFirst = index === 0 ;
var isLast = index === object . attributes . length - 1 ;
if ( isFirst ) {
2014-01-03 15:54:38 +00:00
utils . append ( '{' , state ) ;
2013-12-16 22:19:36 +00:00
}
2014-01-03 15:54:38 +00:00
utils . append ( quoteAttrName ( name ) , state ) ;
utils . append ( ':' , state ) ;
2013-12-16 22:19:36 +00:00
if ( ! attr . value ) {
state . g . buffer += 'true' ;
state . g . position = attr . name . range [ 1 ] ;
if ( ! isLast ) {
2014-01-03 15:54:38 +00:00
utils . append ( ',' , state ) ;
2013-12-16 22:19:36 +00:00
}
} else {
2014-01-03 15:54:38 +00:00
utils . move ( attr . name . range [ 1 ] , state ) ;
2013-12-16 22:19:36 +00:00
// Use catchupWhiteSpace to skip over the '=' in the attribute
2014-01-03 15:54:38 +00:00
utils . catchupWhiteSpace ( attr . value . range [ 0 ] , state ) ;
2013-12-16 22:19:36 +00:00
if ( JSX _ATTRIBUTE _TRANSFORMS [ attr . name . name ] ) {
2014-01-03 15:54:38 +00:00
utils . append ( JSX _ATTRIBUTE _TRANSFORMS [ attr . name . name ] ( attr ) , state ) ;
utils . move ( attr . value . range [ 1 ] , state ) ;
2013-12-16 22:19:36 +00:00
if ( ! isLast ) {
2014-01-03 15:54:38 +00:00
utils . append ( ',' , state ) ;
2013-12-16 22:19:36 +00:00
}
} else if ( attr . value . type === Syntax . Literal ) {
renderXJSLiteral ( attr . value , isLast , state ) ;
} else {
renderXJSExpressionContainer ( traverse , attr . value , isLast , path , state ) ;
}
}
if ( isLast ) {
2014-01-03 15:54:38 +00:00
utils . append ( '}' , state ) ;
2013-12-16 22:19:36 +00:00
}
2014-01-03 15:54:38 +00:00
utils . catchup ( attr . range [ 1 ] , state ) ;
2013-12-16 22:19:36 +00:00
} ) ;
if ( ! object . selfClosing ) {
2014-01-03 15:54:38 +00:00
utils . catchup ( object . openingElement . range [ 1 ] - 1 , state ) ;
utils . move ( object . openingElement . range [ 1 ] , state ) ;
2013-12-16 22:19:36 +00:00
}
// filter out whitespace
if ( childrenToRender . length > 0 ) {
2014-01-03 15:54:38 +00:00
utils . append ( ', ' , state ) ;
2013-12-16 22:19:36 +00:00
object . children . forEach ( function ( child ) {
if ( child . type === Syntax . Literal && ! child . value . match ( /\S/ ) ) {
return ;
}
2014-01-03 15:54:38 +00:00
utils . catchup ( child . range [ 0 ] , state ) ;
2013-12-16 22:19:36 +00:00
var isLast = child === childrenToRender [ childrenToRender . length - 1 ] ;
if ( child . type === Syntax . Literal ) {
renderXJSLiteral ( child , isLast , state ) ;
} else if ( child . type === Syntax . XJSExpressionContainer ) {
renderXJSExpressionContainer ( traverse , child , isLast , path , state ) ;
} else {
traverse ( child , path , state ) ;
if ( ! isLast ) {
2014-01-03 15:54:38 +00:00
utils . append ( ',' , state ) ;
2013-12-16 22:19:36 +00:00
state . g . buffer = state . g . buffer . replace ( /(\s*),$/ , ',$1' ) ;
}
}
2014-01-03 15:54:38 +00:00
utils . catchup ( child . range [ 1 ] , state ) ;
2013-12-16 22:19:36 +00:00
} ) ;
}
if ( object . selfClosing ) {
// everything up to />
2014-01-03 15:54:38 +00:00
utils . catchup ( object . openingElement . range [ 1 ] - 2 , state ) ;
utils . move ( object . openingElement . range [ 1 ] , state ) ;
2013-12-16 22:19:36 +00:00
} else {
// everything up to </ sdflksjfd>
2014-01-03 15:54:38 +00:00
utils . catchup ( object . closingElement . range [ 0 ] , state ) ;
utils . move ( object . closingElement . range [ 1 ] , state ) ;
2013-12-16 22:19:36 +00:00
}
2014-01-03 15:54:38 +00:00
utils . append ( ')' , state ) ;
2013-12-16 22:19:36 +00:00
return false ;
}
visitReactTag . test = function ( object , path , state ) {
// only run react when react @jsx namespace is specified in docblock
2014-01-03 15:54:38 +00:00
var jsx = utils . getDocblock ( state ) . jsx ;
2013-12-16 22:19:36 +00:00
return object . type === Syntax . XJSElement && jsx && jsx . length ;
} ;
exports . visitReactTag = visitReactTag ;
2014-01-03 15:54:38 +00:00
} , { "./xjs" : 24 , "esprima-fb" : 5 , "jstransform/src/utils" : 19 } ] , 23 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ * *
* Copyright 2013 Facebook , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/*global exports:true*/
"use strict" ;
var Syntax = require ( 'esprima-fb' ) . Syntax ;
2014-01-03 15:54:38 +00:00
var utils = require ( 'jstransform/src/utils' ) ;
2013-12-16 22:19:36 +00:00
/ * *
* Transforms the following :
*
* var MyComponent = React . createClass ( {
* render : ...
* } ) ;
*
* into :
*
* var MyComponent = React . createClass ( {
* displayName : 'MyComponent' ,
* render : ...
* } ) ;
* /
function visitReactDisplayName ( traverse , object , path , state ) {
if ( object . id . type === Syntax . Identifier &&
object . init &&
object . init . type === Syntax . CallExpression &&
object . init . callee . type === Syntax . MemberExpression &&
object . init . callee . object . type === Syntax . Identifier &&
object . init . callee . object . name === 'React' &&
object . init . callee . property . type === Syntax . Identifier &&
object . init . callee . property . name === 'createClass' &&
object . init [ 'arguments' ] . length === 1 &&
object . init [ 'arguments' ] [ 0 ] . type === Syntax . ObjectExpression ) {
var displayName = object . id . name ;
2014-01-03 15:54:38 +00:00
utils . catchup ( object . init [ 'arguments' ] [ 0 ] . range [ 0 ] + 1 , state ) ;
utils . append ( "displayName: '" + displayName + "'," , state ) ;
2013-12-16 22:19:36 +00:00
}
}
/ * *
* Will only run on @ jsx files for now .
* /
visitReactDisplayName . test = function ( object , path , state ) {
2014-01-03 15:54:38 +00:00
return object . type === Syntax . VariableDeclarator && ! ! utils . getDocblock ( state ) . jsx ;
2013-12-16 22:19:36 +00:00
} ;
exports . visitReactDisplayName = visitReactDisplayName ;
2014-01-03 15:54:38 +00:00
} , { "esprima-fb" : 5 , "jstransform/src/utils" : 19 } ] , 24 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/ * *
* Copyright 2013 Facebook , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/*global exports:true*/
"use strict" ;
var append = require ( 'jstransform/src/utils' ) . append ;
var catchup = require ( 'jstransform/src/utils' ) . catchup ;
var move = require ( 'jstransform/src/utils' ) . move ;
var Syntax = require ( 'esprima-fb' ) . Syntax ;
var knownTags = {
a : true ,
abbr : true ,
address : true ,
applet : true ,
area : true ,
article : true ,
aside : true ,
audio : true ,
b : true ,
base : true ,
bdi : true ,
bdo : true ,
big : true ,
blockquote : true ,
body : true ,
br : true ,
button : true ,
canvas : true ,
caption : true ,
circle : true ,
cite : true ,
code : true ,
col : true ,
colgroup : true ,
command : true ,
data : true ,
datalist : true ,
dd : true ,
del : true ,
details : true ,
dfn : true ,
dialog : true ,
div : true ,
dl : true ,
dt : true ,
ellipse : true ,
em : true ,
embed : true ,
fieldset : true ,
figcaption : true ,
figure : true ,
footer : true ,
form : true ,
g : true ,
h1 : true ,
h2 : true ,
h3 : true ,
h4 : true ,
h5 : true ,
h6 : true ,
head : true ,
header : true ,
hgroup : true ,
hr : true ,
html : true ,
i : true ,
iframe : true ,
img : true ,
input : true ,
ins : true ,
kbd : true ,
keygen : true ,
label : true ,
legend : true ,
li : true ,
line : true ,
link : true ,
main : true ,
map : true ,
mark : true ,
marquee : true ,
menu : true ,
menuitem : true ,
meta : true ,
meter : true ,
nav : true ,
noscript : true ,
object : true ,
ol : true ,
optgroup : true ,
option : true ,
output : true ,
p : true ,
param : true ,
path : true ,
polyline : true ,
pre : true ,
progress : true ,
q : true ,
rect : true ,
rp : true ,
rt : true ,
ruby : true ,
s : true ,
samp : true ,
script : true ,
section : true ,
select : true ,
small : true ,
source : true ,
span : true ,
strong : true ,
style : true ,
sub : true ,
summary : true ,
sup : true ,
svg : true ,
table : true ,
tbody : true ,
td : true ,
text : true ,
textarea : true ,
tfoot : true ,
th : true ,
thead : true ,
time : true ,
title : true ,
tr : true ,
track : true ,
u : true ,
ul : true ,
'var' : true ,
video : true ,
wbr : true
} ;
function safeTrim ( string ) {
return string . replace ( /^[ \t]+/ , '' ) . replace ( /[ \t]+$/ , '' ) ;
}
// Replace all trailing whitespace characters with a single space character
function trimWithSingleSpace ( string ) {
return string . replace ( /^[ \t\xA0]{2,}/ , ' ' ) .
replace ( /[ \t\xA0]{2,}$/ , ' ' ) . replace ( /^\s+$/ , '' ) ;
}
/ * *
* Special handling for multiline string literals
* print lines :
*
* line
* line
*
* as :
*
* "line " +
* "line"
* /
function renderXJSLiteral ( object , isLast , state , start , end ) {
/** Added blank check filtering and triming*/
var trimmedChildValue = safeTrim ( object . value ) ;
var hasFinalNewLine = false ;
if ( trimmedChildValue ) {
// head whitespace
append ( object . value . match ( /^[\t ]*/ ) [ 0 ] , state ) ;
if ( start ) {
append ( start , state ) ;
}
var trimmedChildValueWithSpace = trimWithSingleSpace ( object . value ) ;
/ * *
* /
var initialLines = trimmedChildValue . split ( /\r\n|\n|\r/ ) ;
var lines = initialLines . filter ( function ( line ) {
return safeTrim ( line ) . length > 0 ;
} ) ;
var hasInitialNewLine = initialLines [ 0 ] !== lines [ 0 ] ;
hasFinalNewLine =
initialLines [ initialLines . length - 1 ] !== lines [ lines . length - 1 ] ;
var numLines = lines . length ;
lines . forEach ( function ( line , ii ) {
var lastLine = ii === numLines - 1 ;
var trimmedLine = safeTrim ( line ) ;
if ( trimmedLine === '' && ! lastLine ) {
append ( line , state ) ;
} else {
var preString = '' ;
var postString = '' ;
var leading = line . match ( /^[ \t]*/ ) [ 0 ] ;
if ( ii === 0 ) {
if ( hasInitialNewLine ) {
preString = ' ' ;
leading = '\n' + leading ;
}
if ( trimmedChildValueWithSpace . substring ( 0 , 1 ) === ' ' ) {
// If this is the first line, and the original content starts with
// whitespace, place a single space at the beginning.
preString = ' ' ;
}
}
if ( ! lastLine || trimmedChildValueWithSpace . substr (
trimmedChildValueWithSpace . length - 1 , 1 ) === ' ' ||
hasFinalNewLine
) {
// If either not on the last line, or the original content ends with
// whitespace, place a single character at the end.
postString = ' ' ;
}
append (
leading +
JSON . stringify (
preString + trimmedLine + postString
) +
( lastLine ? '' : '+' ) +
line . match ( /[ \t]*$/ ) [ 0 ] ,
state ) ;
}
if ( ! lastLine ) {
append ( '\n' , state ) ;
}
} ) ;
} else {
if ( start ) {
append ( start , state ) ;
}
append ( '""' , state ) ;
}
if ( end ) {
append ( end , state ) ;
}
// add comma before trailing whitespace
if ( ! isLast ) {
append ( ',' , state ) ;
}
// tail whitespace
if ( hasFinalNewLine ) {
append ( '\n' , state ) ;
}
append ( object . value . match ( /[ \t]*$/ ) [ 0 ] , state ) ;
move ( object . range [ 1 ] , state ) ;
}
function renderXJSExpressionContainer ( traverse , object , isLast , path , state ) {
// Plus 1 to skip `{`.
move ( object . range [ 0 ] + 1 , state ) ;
traverse ( object . expression , path , state ) ;
if ( ! isLast && object . expression . type !== Syntax . XJSEmptyExpression ) {
// If we need to append a comma, make sure to do so after the expression.
catchup ( object . expression . range [ 1 ] , state ) ;
append ( ',' , state ) ;
}
// Minus 1 to skip `}`.
catchup ( object . range [ 1 ] - 1 , state ) ;
move ( object . range [ 1 ] , state ) ;
return false ;
}
function quoteAttrName ( attr ) {
// Quote invalid JS identifiers.
if ( ! /^[a-z_$][a-z\d_$]*$/i . test ( attr ) ) {
return "'" + attr + "'" ;
}
return attr ;
}
exports . knownTags = knownTags ;
exports . renderXJSExpressionContainer = renderXJSExpressionContainer ;
exports . renderXJSLiteral = renderXJSLiteral ;
exports . quoteAttrName = quoteAttrName ;
2014-01-03 15:54:38 +00:00
} , { "esprima-fb" : 5 , "jstransform/src/utils" : 19 } ] , 25 : [ function ( require , module , exports ) {
2013-12-16 22:19:36 +00:00
/*global exports:true*/
var es6Classes = require ( 'jstransform/visitors/es6-class-visitors' ) . visitorList ;
var react = require ( './transforms/react' ) ;
var reactDisplayName = require ( './transforms/reactDisplayName' ) ;
/ * *
* Map from transformName => orderedListOfVisitors .
* /
var transformVisitors = {
'es6-classes' : es6Classes ,
'react' : [
react . visitReactTag ,
reactDisplayName . visitReactDisplayName
]
} ;
/ * *
* Specifies the order in which each transform should run .
* /
var transformRunOrder = [
'es6-classes' ,
'react'
] ;
/ * *
* Given a list of transform names , return the ordered list of visitors to be
* passed to the transform ( ) function .
*
* @ param { array ? } excludes
* @ return { array }
* /
function getVisitorsList ( excludes ) {
var ret = [ ] ;
for ( var i = 0 , il = transformRunOrder . length ; i < il ; i ++ ) {
if ( ! excludes || excludes . indexOf ( transformRunOrder [ i ] ) === - 1 ) {
ret = ret . concat ( transformVisitors [ transformRunOrder [ i ] ] ) ;
}
}
return ret ;
}
exports . getVisitorsList = getVisitorsList ;
exports . transformVisitors = transformVisitors ;
2014-01-03 15:54:38 +00:00
} , { "./transforms/react" : 22 , "./transforms/reactDisplayName" : 23 , "jstransform/visitors/es6-class-visitors" : 20 } ] } , { } , [ 21 ] )
( 21 )
2013-12-16 22:19:36 +00:00
} ) ;
;