import skipRegex = require ( 'skip-regex' ) ; import R = require ( './regexes' ) ; /** Flag for ES6 TL in the stack */ const ES6_BQ = '`' ; param buffer param start param stack returns const skipES6TL = ( buffer , start , stack ) => { const re = /[`$\\]/g ; re . lastIndex = start + 1 ; while ( re . exec ( buffer ) ) { const pos = re . lastIndex ; const c = buffer [ pos - 1 ] ; if ( c === ES6_BQ ) { return pos ; } if ( c === '$' && buffer [ pos ] === '{' ) { stack . push ( ES6_BQ ) ; return pos + 1 ; } re . lastIndex = pos + 1 ; } return buffer . length ; } ; param expr param start param stack const skipBracket = ( expr , start , stack ) => { const ch = stack . pop ( ) ; if ( ch === '`' ) { return skipES6TL ( expr , start , stack ) ; } return ch ? start + 1 : expr . length ; } ; /**
 * To find the comment (//), it is necessary to skip strings, es6 tl,
 * brackets, and regexes
 */ const RE_EXPR = RegExp ( R . S_STRINGS + '|[`/{}]' , 'g' ) ; param expr param start const extractExpr = function ( expr , start ) { const stack = [ ] ; const re = new RegExp ( RE_EXPR ) ; re . lastIndex = start ; let mm ; while ( mm = re . exec ( expr ) ) { switch ( mm [ 0 ] ) { case '{' : stack . push ( '}' ) ; break ; case '}' : re . lastIndex = skipBracket ( expr , mm . index , stack ) ; break ; case '`' : re . lastIndex = skipES6TL ( expr , mm . index , stack ) ; break ; case '/' : if ( expr [ mm . index + 1 ] === '/' ) { return expr . slice ( 0 , mm . index ) ; } re . lastIndex = skipRegex ( expr , mm . index ) ; } } return expr ; } ; param key param expr const getExpr = function ( key , expr ) { if ( expr . indexOf ( '/' ) < 0 ) { return expr . trim ( ) ; } if ( key === 'set' ) { const mm = R . ASSIGNMENT . exec ( expr ) ! ; const ss = mm && mm [ 2 ] ; if ( ss ) { expr = ss . startsWith ( '//' ) ? mm [ 1 ] : `${ mm [ 1 ] }=${ ss }` ; } } return extractExpr ( expr , 0 ) . trim ( ) ; } ; export = getExpr ;