2019-11-19 20:48:29 +08:00
( function ( global , factory ) {
2020-01-20 05:29:54 +08:00
typeof exports === 'object' && typeof module !== 'undefined' ? factory ( exports ) :
typeof define === 'function' && define . amd ? define ( [ 'exports' ] , factory ) :
( global = global || self , factory ( global . doc = { } ) ) ;
} ( this , ( function ( exports ) { 'use strict' ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
/ * *
* @ param { Doc [ ] } parts
* @ returns Doc
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function concat ( parts ) {
// access the internals of a document directly.
// if(parts.length === 1) {
// // If it's a single document, no need to concat it.
// return parts[0];
// }
return {
type : "concat" ,
parts : parts
} ;
}
/ * *
* @ param { Doc } contents
* @ returns Doc
* /
function indent ( contents ) {
return {
type : "indent" ,
contents : contents
} ;
}
/ * *
* @ param { number } n
* @ param { Doc } contents
* @ returns Doc
* /
function align ( n , contents ) {
return {
type : "align" ,
contents : contents ,
n : n
} ;
}
/ * *
* @ param { Doc } contents
* @ param { object } [ opts ] - TBD ? ? ?
* @ returns Doc
* /
function group ( contents , opts ) {
opts = opts || { } ;
return {
type : "group" ,
id : opts . id ,
contents : contents ,
break : ! ! opts . shouldBreak ,
expandedStates : opts . expandedStates
} ;
}
/ * *
* @ param { Doc } contents
* @ returns Doc
* /
function dedentToRoot ( contents ) {
return align ( - Infinity , contents ) ;
}
/ * *
* @ param { Doc } contents
* @ returns Doc
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function markAsRoot ( contents ) {
// @ts-ignore - TBD ???:
return align ( {
type : "root"
} , contents ) ;
}
/ * *
* @ param { Doc } contents
* @ returns Doc
* /
function dedent ( contents ) {
return align ( - 1 , contents ) ;
}
/ * *
* @ param { Doc [ ] } states
* @ param { object } [ opts ] - TBD ? ? ?
* @ returns Doc
* /
function conditionalGroup ( states , opts ) {
return group ( states [ 0 ] , Object . assign ( opts || { } , {
expandedStates : states
} ) ) ;
}
/ * *
* @ param { Doc [ ] } parts
* @ returns Doc
* /
function fill ( parts ) {
return {
type : "fill" ,
parts : parts
} ;
}
/ * *
* @ param { Doc } [ breakContents ]
* @ param { Doc } [ flatContents ]
* @ param { object } [ opts ] - TBD ? ? ?
* @ returns Doc
* /
function ifBreak ( breakContents , flatContents , opts ) {
opts = opts || { } ;
return {
type : "if-break" ,
breakContents : breakContents ,
flatContents : flatContents ,
groupId : opts . groupId
} ;
}
/ * *
* @ param { Doc } contents
* @ returns Doc
* /
function lineSuffix ( contents ) {
return {
type : "line-suffix" ,
contents : contents
} ;
}
var lineSuffixBoundary = {
type : "line-suffix-boundary"
} ;
var breakParent = {
type : "break-parent"
} ;
var trim = {
type : "trim"
2019-11-19 20:48:29 +08:00
} ;
2020-01-20 05:29:54 +08:00
var line = {
type : "line"
2019-11-19 20:48:29 +08:00
} ;
2020-01-20 05:29:54 +08:00
var softline = {
type : "line" ,
soft : true
} ;
var hardline = concat ( [ {
type : "line" ,
hard : true
} , breakParent ] ) ;
var literalline = concat ( [ {
type : "line" ,
hard : true ,
literal : true
} , breakParent ] ) ;
var cursor = {
type : "cursor" ,
placeholder : Symbol ( "cursor" )
} ;
/ * *
* @ param { Doc } sep
* @ param { Doc [ ] } arr
* @ returns Doc
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function join ( sep , arr ) {
var res = [ ] ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
for ( var i = 0 ; i < arr . length ; i ++ ) {
if ( i !== 0 ) {
res . push ( sep ) ;
}
res . push ( arr [ i ] ) ;
}
return concat ( res ) ;
}
/ * *
* @ param { Doc } doc
* @ param { number } size
* @ param { number } tabWidth
* /
function addAlignmentToDoc ( doc , size , tabWidth ) {
var aligned = doc ;
if ( size > 0 ) {
// Use indent to add tabs for all the levels of tabs we need
for ( var i = 0 ; i < Math . floor ( size / tabWidth ) ; ++ i ) {
aligned = indent ( aligned ) ;
} // Use align for all the spaces that are needed
aligned = align ( size % tabWidth , aligned ) ; // size is absolute from 0 and not relative to the current
// indentation, so we use -Infinity to reset the indentation to 0
aligned = align ( - Infinity , aligned ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return aligned ;
}
var docBuilders = {
concat : concat ,
join : join ,
line : line ,
softline : softline ,
hardline : hardline ,
literalline : literalline ,
group : group ,
conditionalGroup : conditionalGroup ,
fill : fill ,
lineSuffix : lineSuffix ,
lineSuffixBoundary : lineSuffixBoundary ,
cursor : cursor ,
breakParent : breakParent ,
ifBreak : ifBreak ,
trim : trim ,
indent : indent ,
align : align ,
addAlignmentToDoc : addAlignmentToDoc ,
markAsRoot : markAsRoot ,
dedentToRoot : dedentToRoot ,
dedent : dedent
2019-11-19 20:48:29 +08:00
} ;
2020-01-20 05:29:54 +08:00
var ansiRegex = function ansiRegex ( options ) {
2019-11-19 20:48:29 +08:00
options = Object . assign ( {
onlyFirst : false
} , options ) ;
2020-01-20 05:29:54 +08:00
var pattern = [ "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)" , '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' ] . join ( '|' ) ;
2019-11-19 20:48:29 +08:00
return new RegExp ( pattern , options . onlyFirst ? undefined : 'g' ) ;
} ;
2020-01-20 05:29:54 +08:00
var stripAnsi = function stripAnsi ( string ) {
return typeof string === 'string' ? string . replace ( ansiRegex ( ) , '' ) : string ;
} ;
var stripAnsi _1 = stripAnsi ;
var default _1 = stripAnsi ;
stripAnsi _1 . default = default _1 ;
2019-11-19 20:48:29 +08:00
/* eslint-disable yoda */
2020-01-20 05:29:54 +08:00
var isFullwidthCodePoint = function isFullwidthCodePoint ( codePoint ) {
if ( Number . isNaN ( codePoint ) ) {
2019-11-19 20:48:29 +08:00
return false ;
2020-01-20 05:29:54 +08:00
} // Code points are derived from:
2019-11-19 20:48:29 +08:00
// http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
2020-01-20 05:29:54 +08:00
if ( codePoint >= 0x1100 && ( codePoint <= 0x115F || // Hangul Jamo
codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET
codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET
2019-11-19 20:48:29 +08:00
// CJK Radicals Supplement .. Enclosed CJK Letters and Months
2020-01-20 05:29:54 +08:00
0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F || // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
0x3250 <= codePoint && codePoint <= 0x4DBF || // CJK Unified Ideographs .. Yi Radicals
0x4E00 <= codePoint && codePoint <= 0xA4C6 || // Hangul Jamo Extended-A
0xA960 <= codePoint && codePoint <= 0xA97C || // Hangul Syllables
0xAC00 <= codePoint && codePoint <= 0xD7A3 || // CJK Compatibility Ideographs
0xF900 <= codePoint && codePoint <= 0xFAFF || // Vertical Forms
0xFE10 <= codePoint && codePoint <= 0xFE19 || // CJK Compatibility Forms .. Small Form Variants
0xFE30 <= codePoint && codePoint <= 0xFE6B || // Halfwidth and Fullwidth Forms
0xFF01 <= codePoint && codePoint <= 0xFF60 || 0xFFE0 <= codePoint && codePoint <= 0xFFE6 || // Kana Supplement
0x1B000 <= codePoint && codePoint <= 0x1B001 || // Enclosed Ideographic Supplement
0x1F200 <= codePoint && codePoint <= 0x1F251 || // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
0x20000 <= codePoint && codePoint <= 0x3FFFD ) ) {
2019-11-19 20:48:29 +08:00
return true ;
}
return false ;
} ;
2020-01-20 05:29:54 +08:00
var isFullwidthCodePoint _1 = isFullwidthCodePoint ;
var default _1$1 = isFullwidthCodePoint ;
isFullwidthCodePoint _1 . default = default _1$1 ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var emojiRegex = function emojiRegex ( ) {
// https://mths.be/emoji
return / \ u D 8 3 C \ u D F F 4 \ u D B 4 0 \ u D C 6 7 \ u D B 4 0 \ u D C 6 2 ( ? : \ u D B 4 0 \ u D C 6 5 \ u D B 4 0 \ u D C 6 E \ u D B 4 0 \ u D C 6 7 | \ u D B 4 0 \ u D C 7 3 \ u D B 4 0 \ u D C 6 3 \ u D B 4 0 \ u D C 7 4 | \ u D B 4 0 \ u D C 7 7 \ u D B 4 0 \ u D C 6 C \ u D B 4 0 \ u D C 7 3 ) \ u D B 4 0 \ u D C 7 F | \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C \ u D F F C \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 \ u D 8 3 C \ u D F F B | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F F \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F E ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F E \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F D ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F D \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B \ u D F F C ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u 2 0 0 D ( ? : \ u 2 7 6 4 \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? \ u D 8 3 D \ u D C 6 8 | ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 6 6 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 6 | \ u D 8 3 D \ u D C 6 7 \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) ) | \ u D 8 3 D \ u D C 6 6 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 6 | \ u D 8 3 D \ u D C 6 7 \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) | ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) | [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] \ u F E 0 F | \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | ( ? : \ u D 8 3 C \ u D F F B \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F F \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F E \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F D \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F C \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] ) \ u F E 0 F | \ u D 8 3 C \ u D F F B \ u 2 0 0 D ( ? : \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F B \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F C \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 9 ) \ u D 8 3 C \ u D F F B | \ u D 8 3 E \ u D D D 1 ( ? : \ u D 8 3 C \ u D F F F \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 E \ u D D D 1 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) | \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 E \ u D D D 1 ) | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F E \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F F \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) ) ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F E ] ) | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F C \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F D \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 9 ) ( ? : \ u D 8 3 C [ \ u D F F B \ u D F F C ] ) | \ u D 8 3 D \ u D C 6 9 ( ? : \ u D 8 3 C \ u D F F E \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F D \ u D F F F ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F C \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B \ u D F F D - \ u D F F F ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F B \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F C - \ u D F F F ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F D \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B \ u D F F C \ u D F F E \ u D F F F ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u 2 0 0 D ( ? : \ u 2 7 6 4 \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) | \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F F \ u 2 0 0 D ( ? : \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) ) | \ u D 8 3 D \ u D C 6 9 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 9 \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 6 6 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 6 | \ u D 8 3 D \ u D C 6 7 \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) ) | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F D \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F E \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 9 ) ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F D ] ) | \ u D 8 3 D \ u D C 6 9 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 6 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 6 | \ u D 8 3 D \ u D C 6 9 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 9 \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) | ( ? : \ u D 8 3 D \ u D C 4 1 \ u F E 0 F \ u 2 0 0
} ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var stringWidth = function stringWidth ( string ) {
string = string . replace ( emojiRegex ( ) , ' ' ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( typeof string !== 'string' || string . length === 0 ) {
2019-11-19 20:48:29 +08:00
return 0 ;
}
2020-01-20 05:29:54 +08:00
string = stripAnsi _1 ( string ) ;
2019-11-19 20:48:29 +08:00
var width = 0 ;
2020-01-20 05:29:54 +08:00
for ( var i = 0 ; i < string . length ; i ++ ) {
var code = string . codePointAt ( i ) ; // Ignore control characters
2019-11-19 20:48:29 +08:00
if ( code <= 0x1F || code >= 0x7F && code <= 0x9F ) {
continue ;
} // Ignore combining characters
if ( code >= 0x300 && code <= 0x36F ) {
continue ;
} // Surrogates
if ( code > 0xFFFF ) {
i ++ ;
}
2020-01-20 05:29:54 +08:00
width += isFullwidthCodePoint _1 ( code ) ? 2 : 1 ;
2019-11-19 20:48:29 +08:00
}
return width ;
} ;
2020-01-20 05:29:54 +08:00
var stringWidth _1 = stringWidth ; // TODO: remove this in the next major version
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var default _1$2 = stringWidth ;
stringWidth _1 . default = default _1$2 ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g ;
var escapeStringRegexp = function escapeStringRegexp ( str ) {
if ( typeof str !== 'string' ) {
throw new TypeError ( 'Expected a string' ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return str . replace ( matchOperatorsRe , '\\$&' ) ;
} ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var getLast = function getLast ( arr ) {
return arr . length > 0 ? arr [ arr . length - 1 ] : null ;
} ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var notAsciiRegex = /[^\x20-\x7F]/ ;
function isExportDeclaration ( node ) {
if ( node ) {
switch ( node . type ) {
case "ExportDefaultDeclaration" :
case "ExportDefaultSpecifier" :
case "DeclareExportDeclaration" :
case "ExportNamedDeclaration" :
case "ExportAllDeclaration" :
return true ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
return false ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function getParentExportDeclaration ( path ) {
var parentNode = path . getParentNode ( ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( path . getName ( ) === "declaration" && isExportDeclaration ( parentNode ) ) {
return parentNode ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return null ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function getPenultimate ( arr ) {
if ( arr . length > 1 ) {
return arr [ arr . length - 2 ] ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return null ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ typedef { { backwards ? : boolean } } SkipOptions
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string | RegExp } chars
* @ returns { ( text : string , index : number | false , opts ? : SkipOptions ) => number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function skip ( chars ) {
return function ( text , index , opts ) {
var backwards = opts && opts . backwards ; // Allow `skip` functions to be threaded together without having
// to check for failures (did someone say monads?).
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( index === false ) {
return false ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var length = text . length ;
var cursor = index ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
while ( cursor >= 0 && cursor < length ) {
var c = text . charAt ( cursor ) ;
if ( chars instanceof RegExp ) {
if ( ! chars . test ( c ) ) {
return cursor ;
}
} else if ( chars . indexOf ( c ) === - 1 ) {
2019-11-19 20:48:29 +08:00
return cursor ;
}
2020-01-20 05:29:54 +08:00
backwards ? cursor -- : cursor ++ ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( cursor === - 1 || cursor === length ) {
// If we reached the beginning or end of the file, return the
// out-of-bounds cursor. It's up to the caller to handle this
// correctly. We don't want to indicate `false` though if it
// actually skipped valid characters.
return cursor ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return false ;
} ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ type { ( text : string , index : number | false , opts ? : SkipOptions ) => number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var skipWhitespace = skip ( /\s/ ) ;
/ * *
* @ type { ( text : string , index : number | false , opts ? : SkipOptions ) => number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var skipSpaces = skip ( " \t" ) ;
/ * *
* @ type { ( text : string , index : number | false , opts ? : SkipOptions ) => number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var skipToLineEnd = skip ( ",; \t" ) ;
/ * *
* @ type { ( text : string , index : number | false , opts ? : SkipOptions ) => number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var skipEverythingButNewLine = skip ( /[^\r\n]/ ) ;
/ * *
* @ param { string } text
* @ param { number | false } index
* @ returns { number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function skipInlineComment ( text , index ) {
if ( index === false ) {
return false ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( text . charAt ( index ) === "/" && text . charAt ( index + 1 ) === "*" ) {
for ( var i = index + 2 ; i < text . length ; ++ i ) {
if ( text . charAt ( i ) === "*" && text . charAt ( i + 1 ) === "/" ) {
return i + 2 ;
}
}
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return index ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } text
* @ param { number | false } index
* @ returns { number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function skipTrailingComment ( text , index ) {
if ( index === false ) {
return false ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
if ( text . charAt ( index ) === "/" && text . charAt ( index + 1 ) === "/" ) {
return skipEverythingButNewLine ( text , index ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
return index ;
} // This one doesn't use the above helper function because it wants to
// test \r\n in order and `skip` doesn't support ordering and we only
// want to skip one newline. It's simple to implement.
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } text
* @ param { number | false } index
* @ param { SkipOptions = } opts
* @ returns { number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function skipNewline ( text , index , opts ) {
var backwards = opts && opts . backwards ;
if ( index === false ) {
return false ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
var atIndex = text . charAt ( index ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( backwards ) {
if ( text . charAt ( index - 1 ) === "\r" && atIndex === "\n" ) {
return index - 2 ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029" ) {
return index - 1 ;
}
} else {
if ( atIndex === "\r" && text . charAt ( index + 1 ) === "\n" ) {
return index + 2 ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029" ) {
return index + 1 ;
}
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return index ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } text
* @ param { number } index
* @ param { SkipOptions = } opts
* @ returns { boolean }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function hasNewline ( text , index , opts ) {
opts = opts || { } ;
var idx = skipSpaces ( text , opts . backwards ? index - 1 : index , opts ) ;
var idx2 = skipNewline ( text , idx , opts ) ;
return idx !== idx2 ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } text
* @ param { number } start
* @ param { number } end
* @ returns { boolean }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function hasNewlineInRange ( text , start , end ) {
for ( var i = start ; i < end ; ++ i ) {
if ( text . charAt ( i ) === "\n" ) {
return true ;
}
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return false ;
} // Note: this function doesn't ignore leading comments unlike isNextLineEmpty
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
/ * *
* @ template N
* @ param { string } text
* @ param { N } node
* @ param { ( node : N ) => number } locStart
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function isPreviousLineEmpty ( text , node , locStart ) {
/** @type {number | false} */
var idx = locStart ( node ) - 1 ;
idx = skipSpaces ( text , idx , {
backwards : true
} ) ;
idx = skipNewline ( text , idx , {
backwards : true
} ) ;
idx = skipSpaces ( text , idx , {
backwards : true
} ) ;
var idx2 = skipNewline ( text , idx , {
backwards : true
} ) ;
return idx !== idx2 ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } text
* @ param { number } index
* @ returns { boolean }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function isNextLineEmptyAfterIndex ( text , index ) {
/** @type {number | false} */
var oldIdx = null ;
/** @type {number | false} */
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var idx = index ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
while ( idx !== oldIdx ) {
// We need to skip all the potential trailing inline comments
oldIdx = idx ;
idx = skipToLineEnd ( text , idx ) ;
idx = skipInlineComment ( text , idx ) ;
idx = skipSpaces ( text , idx ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
idx = skipTrailingComment ( text , idx ) ;
idx = skipNewline ( text , idx ) ;
return idx !== false && hasNewline ( text , idx ) ;
}
/ * *
* @ template N
* @ param { string } text
* @ param { N } node
* @ param { ( node : N ) => number } locEnd
* @ returns { boolean }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function isNextLineEmpty ( text , node , locEnd ) {
return isNextLineEmptyAfterIndex ( text , locEnd ( node ) ) ;
}
/ * *
* @ param { string } text
* @ param { number } idx
* @ returns { number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getNextNonSpaceNonCommentCharacterIndexWithStartIndex ( text , idx ) {
/** @type {number | false} */
var oldIdx = null ;
/** @type {number | false} */
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var nextIdx = idx ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
while ( nextIdx !== oldIdx ) {
oldIdx = nextIdx ;
nextIdx = skipSpaces ( text , nextIdx ) ;
nextIdx = skipInlineComment ( text , nextIdx ) ;
nextIdx = skipTrailingComment ( text , nextIdx ) ;
nextIdx = skipNewline ( text , nextIdx ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return nextIdx ;
}
/ * *
* @ template N
* @ param { string } text
* @ param { N } node
* @ param { ( node : N ) => number } locEnd
* @ returns { number | false }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getNextNonSpaceNonCommentCharacterIndex ( text , node , locEnd ) {
return getNextNonSpaceNonCommentCharacterIndexWithStartIndex ( text , locEnd ( node ) ) ;
}
/ * *
* @ template N
* @ param { string } text
* @ param { N } node
* @ param { ( node : N ) => number } locEnd
* @ returns { string }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getNextNonSpaceNonCommentCharacter ( text , node , locEnd ) {
return text . charAt ( // @ts-ignore => TBD: can return false, should we define a fallback?
getNextNonSpaceNonCommentCharacterIndex ( text , node , locEnd ) ) ;
}
/ * *
* @ param { string } text
* @ param { number } index
* @ param { SkipOptions = } opts
* @ returns { boolean }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function hasSpaces ( text , index , opts ) {
opts = opts || { } ;
var idx = skipSpaces ( text , opts . backwards ? index - 1 : index , opts ) ;
return idx !== index ;
}
/ * *
* @ param { { range ? : [ number , number ] , start ? : number } } node
* @ param { number } index
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function setLocStart ( node , index ) {
if ( node . range ) {
node . range [ 0 ] = index ;
} else {
node . start = index ;
}
}
/ * *
* @ param { { range ? : [ number , number ] , end ? : number } } node
* @ param { number } index
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function setLocEnd ( node , index ) {
if ( node . range ) {
node . range [ 1 ] = index ;
} else {
node . end = index ;
}
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var PRECEDENCE = { } ;
[ [ "|>" ] , [ "??" ] , [ "||" ] , [ "&&" ] , [ "|" ] , [ "^" ] , [ "&" ] , [ "==" , "===" , "!=" , "!==" ] , [ "<" , ">" , "<=" , ">=" , "in" , "instanceof" ] , [ ">>" , "<<" , ">>>" ] , [ "+" , "-" ] , [ "*" , "/" , "%" ] , [ "**" ] ] . forEach ( function ( tier , i ) {
tier . forEach ( function ( op ) {
PRECEDENCE [ op ] = i ;
} ) ;
} ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getPrecedence ( op ) {
return PRECEDENCE [ op ] ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var equalityOperators = {
"==" : true ,
"!=" : true ,
"===" : true ,
"!==" : true
} ;
var multiplicativeOperators = {
"*" : true ,
"/" : true ,
"%" : true
} ;
var bitshiftOperators = {
">>" : true ,
">>>" : true ,
"<<" : true
} ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function shouldFlatten ( parentOp , nodeOp ) {
if ( getPrecedence ( nodeOp ) !== getPrecedence ( parentOp ) ) {
return false ;
} // ** is right-associative
// x ** y ** z --> x ** (y ** z)
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( parentOp === "**" ) {
2019-11-19 20:48:29 +08:00
return false ;
2020-01-20 05:29:54 +08:00
} // x == y == z --> (x == y) == z
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( equalityOperators [ parentOp ] && equalityOperators [ nodeOp ] ) {
return false ;
} // x * y % z --> (x * y) % z
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( nodeOp === "%" && multiplicativeOperators [ parentOp ] || parentOp === "%" && multiplicativeOperators [ nodeOp ] ) {
return false ;
} // x * y / z --> (x * y) / z
// x / y * z --> (x / y) * z
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( nodeOp !== parentOp && multiplicativeOperators [ nodeOp ] && multiplicativeOperators [ parentOp ] ) {
return false ;
} // x << y << z --> (x << y) << z
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( bitshiftOperators [ parentOp ] && bitshiftOperators [ nodeOp ] ) {
return false ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return true ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function isBitwiseOperator ( operator ) {
return ! ! bitshiftOperators [ operator ] || operator === "|" || operator === "^" || operator === "&" ;
} // Tests if an expression starts with `{`, or (if forbidFunctionClassAndDoExpr
// holds) `function`, `class`, or `do {}`. Will be overzealous if there's
// already necessary grouping parentheses.
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function startsWithNoLookaheadToken ( node , forbidFunctionClassAndDoExpr ) {
node = getLeftMost ( node ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
switch ( node . type ) {
case "FunctionExpression" :
case "ClassExpression" :
case "DoExpression" :
return forbidFunctionClassAndDoExpr ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "ObjectExpression" :
return true ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "MemberExpression" :
case "OptionalMemberExpression" :
return startsWithNoLookaheadToken ( node . object , forbidFunctionClassAndDoExpr ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "TaggedTemplateExpression" :
if ( node . tag . type === "FunctionExpression" ) {
// IIFEs are always already parenthesized
return false ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return startsWithNoLookaheadToken ( node . tag , forbidFunctionClassAndDoExpr ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "CallExpression" :
case "OptionalCallExpression" :
if ( node . callee . type === "FunctionExpression" ) {
// IIFEs are always already parenthesized
return false ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return startsWithNoLookaheadToken ( node . callee , forbidFunctionClassAndDoExpr ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "ConditionalExpression" :
return startsWithNoLookaheadToken ( node . test , forbidFunctionClassAndDoExpr ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "UpdateExpression" :
return ! node . prefix && startsWithNoLookaheadToken ( node . argument , forbidFunctionClassAndDoExpr ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "BindExpression" :
return node . object && startsWithNoLookaheadToken ( node . object , forbidFunctionClassAndDoExpr ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "SequenceExpression" :
return startsWithNoLookaheadToken ( node . expressions [ 0 ] , forbidFunctionClassAndDoExpr ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "TSAsExpression" :
return startsWithNoLookaheadToken ( node . expression , forbidFunctionClassAndDoExpr ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
default :
return false ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function getLeftMost ( node ) {
if ( node . left ) {
return getLeftMost ( node . left ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return node ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } value
* @ param { number } tabWidth
* @ param { number = } startIndex
* @ returns { number }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getAlignmentSize ( value , tabWidth , startIndex ) {
startIndex = startIndex || 0 ;
var size = 0 ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
for ( var i = startIndex ; i < value . length ; ++ i ) {
if ( value [ i ] === "\t" ) {
// Tabs behave in a way that they are aligned to the nearest
// multiple of tabWidth:
// 0 -> 4, 1 -> 4, 2 -> 4, 3 -> 4
// 4 -> 8, 5 -> 8, 6 -> 8, 7 -> 8 ...
size = size + tabWidth - size % tabWidth ;
} else {
size ++ ;
2019-11-19 20:48:29 +08:00
}
}
2020-01-20 05:29:54 +08:00
return size ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } value
* @ param { number } tabWidth
* @ returns { number }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getIndentSize ( value , tabWidth ) {
var lastNewlineIndex = value . lastIndexOf ( "\n" ) ;
if ( lastNewlineIndex === - 1 ) {
return 0 ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
return getAlignmentSize ( // All the leading whitespaces
value . slice ( lastNewlineIndex + 1 ) . match ( /^[ \t]*/ ) [ 0 ] , tabWidth ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ typedef { '"' | "'" } Quote
* /
/ * *
*
* @ param { string } raw
* @ param { Quote } preferredQuote
* @ returns { Quote }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getPreferredQuote ( raw , preferredQuote ) {
// `rawContent` is the string exactly like it appeared in the input source
// code, without its enclosing quotes.
var rawContent = raw . slice ( 1 , - 1 ) ;
/** @type {{ quote: '"', regex: RegExp }} */
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var double = {
quote : '"' ,
regex : /"/g
} ;
/** @type {{ quote: "'", regex: RegExp }} */
var single = {
quote : "'" ,
regex : /'/g
} ;
var preferred = preferredQuote === "'" ? single : double ;
var alternate = preferred === single ? double : single ;
var result = preferred . quote ; // If `rawContent` contains at least one of the quote preferred for enclosing
// the string, we might want to enclose with the alternate quote instead, to
// minimize the number of escaped quotes.
if ( rawContent . includes ( preferred . quote ) || rawContent . includes ( alternate . quote ) ) {
var numPreferredQuotes = ( rawContent . match ( preferred . regex ) || [ ] ) . length ;
var numAlternateQuotes = ( rawContent . match ( alternate . regex ) || [ ] ) . length ;
result = numPreferredQuotes > numAlternateQuotes ? alternate . quote : preferred . quote ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return result ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function printString ( raw , options , isDirectiveLiteral ) {
// `rawContent` is the string exactly like it appeared in the input source
// code, without its enclosing quotes.
var rawContent = raw . slice ( 1 , - 1 ) ; // Check for the alternate quote, to determine if we're allowed to swap
// the quotes on a DirectiveLiteral.
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var canChangeDirectiveQuotes = ! rawContent . includes ( '"' ) && ! rawContent . includes ( "'" ) ;
/** @type {Quote} */
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var enclosingQuote = options . parser === "json" ? '"' : options . _ _isInHtmlAttribute ? "'" : getPreferredQuote ( raw , options . singleQuote ? "'" : '"' ) ; // Directives are exact code unit sequences, which means that you can't
// change the escape sequences they use.
// See https://github.com/prettier/prettier/issues/1555
// and https://tc39.github.io/ecma262/#directive-prologue
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( isDirectiveLiteral ) {
if ( canChangeDirectiveQuotes ) {
return enclosingQuote + rawContent + enclosingQuote ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return raw ;
} // It might sound unnecessary to use `makeString` even if the string already
// is enclosed with `enclosingQuote`, but it isn't. The string could contain
// unnecessary escapes (such as in `"\'"`). Always using `makeString` makes
// sure that we consistently output the minimum amount of escaped quotes.
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return makeString ( rawContent , enclosingQuote , ! ( options . parser === "css" || options . parser === "less" || options . parser === "scss" || options . embeddedInHtml ) ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } rawContent
* @ param { Quote } enclosingQuote
* @ param { boolean = } unescapeUnnecessaryEscapes
* @ returns { string }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function makeString ( rawContent , enclosingQuote , unescapeUnnecessaryEscapes ) {
var otherQuote = enclosingQuote === '"' ? "'" : '"' ; // Matches _any_ escape and unescaped quotes (both single and double).
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var regex = /\\([\s\S])|(['"])/g ; // Escape and unescape single and double quotes as needed to be able to
// enclose `rawContent` with `enclosingQuote`.
var newContent = rawContent . replace ( regex , function ( match , escaped , quote ) {
// If we matched an escape, and the escaped character is a quote of the
// other type than we intend to enclose the string with, there's no need for
// it to be escaped, so return it _without_ the backslash.
if ( escaped === otherQuote ) {
return escaped ;
} // If we matched an unescaped quote and it is of the _same_ type as we
// intend to enclose the string with, it must be escaped, so return it with
// a backslash.
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( quote === enclosingQuote ) {
return "\\" + quote ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( quote ) {
return quote ;
} // Unescape any unnecessarily escaped character.
// Adapted from https://github.com/eslint/eslint/blob/de0b4ad7bd820ade41b1f606008bea68683dc11a/lib/rules/no-useless-escape.js#L27
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return unescapeUnnecessaryEscapes && /^[^\\nrvtbfux\r\n\u2028\u2029"'0-7]$/ . test ( escaped ) ? escaped : "\\" + escaped ;
} ) ;
return enclosingQuote + newContent + enclosingQuote ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function printNumber ( rawNumber ) {
return rawNumber . toLowerCase ( ) // Remove unnecessary plus and zeroes from scientific notation.
. replace ( /^([+-]?[\d.]+e)(?:\+|(-))?0*(\d)/ , "$1$2$3" ) // Remove unnecessary scientific notation (1e0).
. replace ( /^([+-]?[\d.]+)e[+-]?0+$/ , "$1" ) // Make sure numbers always start with a digit.
. replace ( /^([+-])?\./ , "$10." ) // Remove extraneous trailing decimal zeroes.
. replace ( /(\.\d+?)0+(?=e|$)/ , "$1" ) // Remove trailing dot.
. replace ( /\.(?=e|$)/ , "" ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } str
* @ param { string } target
* @ returns { number }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getMaxContinuousCount ( str , target ) {
var results = str . match ( new RegExp ( "(" . concat ( escapeStringRegexp ( target ) , ")+" ) , "g" ) ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( results === null ) {
return 0 ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return results . reduce ( function ( maxCount , result ) {
return Math . max ( maxCount , result . length / target . length ) ;
} , 0 ) ;
}
function getMinNotPresentContinuousCount ( str , target ) {
var matches = str . match ( new RegExp ( "(" . concat ( escapeStringRegexp ( target ) , ")+" ) , "g" ) ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( matches === null ) {
return 0 ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
var countPresent = new Map ( ) ;
var max = 0 ;
var _iteratorNormalCompletion = true ;
var _didIteratorError = false ;
var _iteratorError = undefined ;
2019-11-19 20:48:29 +08:00
try {
2020-01-20 05:29:54 +08:00
for ( var _iterator = matches [ Symbol . iterator ] ( ) , _step ; ! ( _iteratorNormalCompletion = ( _step = _iterator . next ( ) ) . done ) ; _iteratorNormalCompletion = true ) {
var match = _step . value ;
var count = match . length / target . length ;
countPresent . set ( count , true ) ;
if ( count > max ) {
max = count ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
} catch ( err ) {
_didIteratorError = true ;
_iteratorError = err ;
2019-11-19 20:48:29 +08:00
} finally {
2020-01-20 05:29:54 +08:00
try {
if ( ! _iteratorNormalCompletion && _iterator . return != null ) {
_iterator . return ( ) ;
}
} finally {
if ( _didIteratorError ) {
throw _iteratorError ;
}
2019-11-19 20:48:29 +08:00
}
}
2020-01-20 05:29:54 +08:00
for ( var i = 1 ; i < max ; i ++ ) {
if ( ! countPresent . get ( i ) ) {
return i ;
}
}
return max + 1 ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
/ * *
* @ param { string } text
* @ returns { number }
* /
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function getStringWidth ( text ) {
if ( ! text ) {
return 0 ;
} // shortcut to avoid needless string `RegExp`s, replacements, and allocations within `string-width`
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( ! notAsciiRegex . test ( text ) ) {
return text . length ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return stringWidth _1 ( text ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function hasIgnoreComment ( path ) {
var node = path . getValue ( ) ;
return hasNodeIgnoreComment ( node ) ;
}
function hasNodeIgnoreComment ( node ) {
return node && node . comments && node . comments . length > 0 && node . comments . some ( function ( comment ) {
return comment . value . trim ( ) === "prettier-ignore" ;
} ) ;
}
function matchAncestorTypes ( path , types , index ) {
index = index || 0 ;
types = types . slice ( ) ;
while ( types . length ) {
var parent = path . getParentNode ( index ) ;
var type = types . shift ( ) ;
if ( ! parent || parent . type !== type ) {
return false ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
index ++ ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
return true ;
}
function addCommentHelper ( node , comment ) {
var comments = node . comments || ( node . comments = [ ] ) ;
comments . push ( comment ) ;
comment . printed = false ; // For some reason, TypeScript parses `// x` inside of JSXText as a comment
// We already "print" it via the raw text, we don't need to re-print it as a
// comment
if ( node . type === "JSXText" ) {
comment . printed = true ;
2019-11-19 20:48:29 +08:00
}
}
2020-01-20 05:29:54 +08:00
function addLeadingComment ( node , comment ) {
comment . leading = true ;
comment . trailing = false ;
addCommentHelper ( node , comment ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function addDanglingComment ( node , comment ) {
comment . leading = false ;
comment . trailing = false ;
addCommentHelper ( node , comment ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function addTrailingComment ( node , comment ) {
comment . leading = false ;
comment . trailing = true ;
addCommentHelper ( node , comment ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function isWithinParentArrayProperty ( path , propertyName ) {
var node = path . getValue ( ) ;
var parent = path . getParentNode ( ) ;
if ( parent == null ) {
return false ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
if ( ! Array . isArray ( parent [ propertyName ] ) ) {
return false ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
var key = path . getName ( ) ;
return parent [ propertyName ] [ key ] === node ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function replaceEndOfLineWith ( text , replacement ) {
var parts = [ ] ;
var _iteratorNormalCompletion2 = true ;
var _didIteratorError2 = false ;
var _iteratorError2 = undefined ;
try {
for ( var _iterator2 = text . split ( "\n" ) [ Symbol . iterator ] ( ) , _step2 ; ! ( _iteratorNormalCompletion2 = ( _step2 = _iterator2 . next ( ) ) . done ) ; _iteratorNormalCompletion2 = true ) {
var part = _step2 . value ;
if ( parts . length !== 0 ) {
parts . push ( replacement ) ;
}
parts . push ( part ) ;
}
} catch ( err ) {
_didIteratorError2 = true ;
_iteratorError2 = err ;
} finally {
try {
if ( ! _iteratorNormalCompletion2 && _iterator2 . return != null ) {
_iterator2 . return ( ) ;
}
} finally {
if ( _didIteratorError2 ) {
throw _iteratorError2 ;
}
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
return parts ;
}
var util = {
replaceEndOfLineWith : replaceEndOfLineWith ,
getStringWidth : getStringWidth ,
getMaxContinuousCount : getMaxContinuousCount ,
getMinNotPresentContinuousCount : getMinNotPresentContinuousCount ,
getPrecedence : getPrecedence ,
shouldFlatten : shouldFlatten ,
isBitwiseOperator : isBitwiseOperator ,
isExportDeclaration : isExportDeclaration ,
getParentExportDeclaration : getParentExportDeclaration ,
getPenultimate : getPenultimate ,
getLast : getLast ,
getNextNonSpaceNonCommentCharacterIndexWithStartIndex : getNextNonSpaceNonCommentCharacterIndexWithStartIndex ,
getNextNonSpaceNonCommentCharacterIndex : getNextNonSpaceNonCommentCharacterIndex ,
getNextNonSpaceNonCommentCharacter : getNextNonSpaceNonCommentCharacter ,
skip : skip ,
skipWhitespace : skipWhitespace ,
skipSpaces : skipSpaces ,
skipToLineEnd : skipToLineEnd ,
skipEverythingButNewLine : skipEverythingButNewLine ,
skipInlineComment : skipInlineComment ,
skipTrailingComment : skipTrailingComment ,
skipNewline : skipNewline ,
isNextLineEmptyAfterIndex : isNextLineEmptyAfterIndex ,
isNextLineEmpty : isNextLineEmpty ,
isPreviousLineEmpty : isPreviousLineEmpty ,
hasNewline : hasNewline ,
hasNewlineInRange : hasNewlineInRange ,
hasSpaces : hasSpaces ,
setLocStart : setLocStart ,
setLocEnd : setLocEnd ,
startsWithNoLookaheadToken : startsWithNoLookaheadToken ,
getAlignmentSize : getAlignmentSize ,
getIndentSize : getIndentSize ,
getPreferredQuote : getPreferredQuote ,
printString : printString ,
printNumber : printNumber ,
hasIgnoreComment : hasIgnoreComment ,
hasNodeIgnoreComment : hasNodeIgnoreComment ,
makeString : makeString ,
matchAncestorTypes : matchAncestorTypes ,
addLeadingComment : addLeadingComment ,
addDanglingComment : addDanglingComment ,
addTrailingComment : addTrailingComment ,
isWithinParentArrayProperty : isWithinParentArrayProperty
} ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function guessEndOfLine ( text ) {
var index = text . indexOf ( "\r" ) ;
if ( index >= 0 ) {
return text . charAt ( index + 1 ) === "\n" ? "crlf" : "cr" ;
}
return "lf" ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function convertEndOfLineToChars ( value ) {
switch ( value ) {
case "cr" :
return "\r" ;
case "crlf" :
return "\r\n" ;
default :
return "\n" ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
var endOfLine = {
guessEndOfLine : guessEndOfLine ,
convertEndOfLineToChars : convertEndOfLineToChars
} ;
var getStringWidth$1 = util . getStringWidth ;
var convertEndOfLineToChars$1 = endOfLine . convertEndOfLineToChars ;
var concat$1 = docBuilders . concat ,
fill$1 = docBuilders . fill ,
cursor$1 = docBuilders . cursor ;
/** @type {Record<symbol, typeof MODE_BREAK | typeof MODE_FLAT>} */
var groupModeMap ;
var MODE _BREAK = 1 ;
var MODE _FLAT = 2 ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function rootIndent ( ) {
return {
value : "" ,
length : 0 ,
queue : [ ]
} ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function makeIndent ( ind , options ) {
return generateInd ( ind , {
type : "indent"
} , options ) ;
}
function makeAlign ( ind , n , options ) {
return n === - Infinity ? ind . root || rootIndent ( ) : n < 0 ? generateInd ( ind , {
type : "dedent"
} , options ) : ! n ? ind : n . type === "root" ? Object . assign ( { } , ind , {
root : ind
} ) : typeof n === "string" ? generateInd ( ind , {
type : "stringAlign" ,
n : n
} , options ) : generateInd ( ind , {
type : "numberAlign" ,
n : n
} , options ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function generateInd ( ind , newPart , options ) {
var queue = newPart . type === "dedent" ? ind . queue . slice ( 0 , - 1 ) : ind . queue . concat ( newPart ) ;
var value = "" ;
var length = 0 ;
var lastTabs = 0 ;
var lastSpaces = 0 ;
var _iteratorNormalCompletion = true ;
var _didIteratorError = false ;
var _iteratorError = undefined ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
try {
for ( var _iterator = queue [ Symbol . iterator ] ( ) , _step ; ! ( _iteratorNormalCompletion = ( _step = _iterator . next ( ) ) . done ) ; _iteratorNormalCompletion = true ) {
var part = _step . value ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
switch ( part . type ) {
case "indent" :
flush ( ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( options . useTabs ) {
addTabs ( 1 ) ;
} else {
addSpaces ( options . tabWidth ) ;
}
break ;
case "stringAlign" :
flush ( ) ;
value += part . n ;
length += part . n . length ;
break ;
case "numberAlign" :
lastTabs += 1 ;
lastSpaces += part . n ;
break ;
/* istanbul ignore next */
default :
throw new Error ( "Unexpected type '" . concat ( part . type , "'" ) ) ;
}
}
} catch ( err ) {
_didIteratorError = true ;
_iteratorError = err ;
} finally {
try {
if ( ! _iteratorNormalCompletion && _iterator . return != null ) {
_iterator . return ( ) ;
}
} finally {
if ( _didIteratorError ) {
throw _iteratorError ;
}
}
}
flushSpaces ( ) ;
return Object . assign ( { } , ind , {
value : value ,
length : length ,
queue : queue
} ) ;
function addTabs ( count ) {
value += "\t" . repeat ( count ) ;
length += options . tabWidth * count ;
}
function addSpaces ( count ) {
value += " " . repeat ( count ) ;
length += count ;
}
function flush ( ) {
if ( options . useTabs ) {
flushTabs ( ) ;
} else {
flushSpaces ( ) ;
}
}
function flushTabs ( ) {
if ( lastTabs > 0 ) {
addTabs ( lastTabs ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
resetLast ( ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function flushSpaces ( ) {
if ( lastSpaces > 0 ) {
addSpaces ( lastSpaces ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
resetLast ( ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function resetLast ( ) {
lastTabs = 0 ;
lastSpaces = 0 ;
}
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function trim$1 ( out ) {
if ( out . length === 0 ) {
return 0 ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var trimCount = 0 ; // Trim whitespace at the end of line
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
while ( out . length > 0 && typeof out [ out . length - 1 ] === "string" && out [ out . length - 1 ] . match ( /^[ \t]*$/ ) ) {
trimCount += out . pop ( ) . length ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( out . length && typeof out [ out . length - 1 ] === "string" ) {
var trimmed = out [ out . length - 1 ] . replace ( /[ \t]*$/ , "" ) ;
trimCount += out [ out . length - 1 ] . length - trimmed . length ;
out [ out . length - 1 ] = trimmed ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return trimCount ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function fits ( next , restCommands , width , options , mustBeFlat ) {
var restIdx = restCommands . length ;
var cmds = [ next ] ; // `out` is only used for width counting because `trim` requires to look
// backwards for space characters.
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var out = [ ] ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
while ( width >= 0 ) {
if ( cmds . length === 0 ) {
if ( restIdx === 0 ) {
return true ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
cmds . push ( restCommands [ restIdx - 1 ] ) ;
restIdx -- ;
continue ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var x = cmds . pop ( ) ;
var ind = x [ 0 ] ;
var mode = x [ 1 ] ;
var doc = x [ 2 ] ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( typeof doc === "string" ) {
out . push ( doc ) ;
width -= getStringWidth$1 ( doc ) ;
} else {
switch ( doc . type ) {
case "concat" :
for ( var i = doc . parts . length - 1 ; i >= 0 ; i -- ) {
cmds . push ( [ ind , mode , doc . parts [ i ] ] ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
break ;
case "indent" :
cmds . push ( [ makeIndent ( ind , options ) , mode , doc . contents ] ) ;
break ;
case "align" :
cmds . push ( [ makeAlign ( ind , doc . n , options ) , mode , doc . contents ] ) ;
break ;
case "trim" :
width += trim$1 ( out ) ;
break ;
case "group" :
if ( mustBeFlat && doc . break ) {
return false ;
}
cmds . push ( [ ind , doc . break ? MODE _BREAK : mode , doc . contents ] ) ;
if ( doc . id ) {
groupModeMap [ doc . id ] = cmds [ cmds . length - 1 ] [ 1 ] ;
2019-11-19 20:48:29 +08:00
}
break ;
2020-01-20 05:29:54 +08:00
case "fill" :
for ( var _i = doc . parts . length - 1 ; _i >= 0 ; _i -- ) {
cmds . push ( [ ind , mode , doc . parts [ _i ] ] ) ;
}
break ;
case "if-break" :
{
var groupMode = doc . groupId ? groupModeMap [ doc . groupId ] : mode ;
if ( groupMode === MODE _BREAK ) {
if ( doc . breakContents ) {
cmds . push ( [ ind , mode , doc . breakContents ] ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( groupMode === MODE _FLAT ) {
if ( doc . flatContents ) {
cmds . push ( [ ind , mode , doc . flatContents ] ) ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
break ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "line" :
switch ( mode ) {
// fallthrough
case MODE _FLAT :
if ( ! doc . hard ) {
if ( ! doc . soft ) {
out . push ( " " ) ;
width -= 1 ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return true ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case MODE _BREAK :
return true ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
}
}
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return false ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function printDocToString ( doc , options ) {
groupModeMap = { } ;
var width = options . printWidth ;
var newLine = convertEndOfLineToChars$1 ( options . endOfLine ) ;
var pos = 0 ; // cmds is basically a stack. We've turned a recursive call into a
// while loop which is much faster. The while loop below adds new
// cmds to the array instead of recursively calling `print`.
var cmds = [ [ rootIndent ( ) , MODE _BREAK , doc ] ] ;
var out = [ ] ;
var shouldRemeasure = false ;
var lineSuffix = [ ] ;
while ( cmds . length !== 0 ) {
var x = cmds . pop ( ) ;
var ind = x [ 0 ] ;
var mode = x [ 1 ] ;
var _doc = x [ 2 ] ;
if ( typeof _doc === "string" ) {
out . push ( _doc ) ;
pos += getStringWidth$1 ( _doc ) ;
} else {
switch ( _doc . type ) {
case "cursor" :
out . push ( cursor$1 . placeholder ) ;
break ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "concat" :
for ( var i = _doc . parts . length - 1 ; i >= 0 ; i -- ) {
cmds . push ( [ ind , mode , _doc . parts [ i ] ] ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "indent" :
cmds . push ( [ makeIndent ( ind , options ) , mode , _doc . contents ] ) ;
break ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "align" :
cmds . push ( [ makeAlign ( ind , _doc . n , options ) , mode , _doc . contents ] ) ;
break ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "trim" :
pos -= trim$1 ( out ) ;
break ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "group" :
switch ( mode ) {
case MODE _FLAT :
if ( ! shouldRemeasure ) {
cmds . push ( [ ind , _doc . break ? MODE _BREAK : MODE _FLAT , _doc . contents ] ) ;
break ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
// fallthrough
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case MODE _BREAK :
{
shouldRemeasure = false ;
var next = [ ind , MODE _FLAT , _doc . contents ] ;
var rem = width - pos ;
if ( ! _doc . break && fits ( next , cmds , rem , options ) ) {
cmds . push ( next ) ;
} else {
// Expanded states are a rare case where a document
// can manually provide multiple representations of
// itself. It provides an array of documents
// going from the least expanded (most flattened)
// representation first to the most expanded. If a
// group has these, we need to manually go through
// these states and find the first one that fits.
if ( _doc . expandedStates ) {
var mostExpanded = _doc . expandedStates [ _doc . expandedStates . length - 1 ] ;
if ( _doc . break ) {
cmds . push ( [ ind , MODE _BREAK , mostExpanded ] ) ;
break ;
} else {
for ( var _i2 = 1 ; _i2 < _doc . expandedStates . length + 1 ; _i2 ++ ) {
if ( _i2 >= _doc . expandedStates . length ) {
cmds . push ( [ ind , MODE _BREAK , mostExpanded ] ) ;
2019-11-19 20:48:29 +08:00
break ;
2020-01-20 05:29:54 +08:00
} else {
var state = _doc . expandedStates [ _i2 ] ;
var cmd = [ ind , MODE _FLAT , state ] ;
if ( fits ( cmd , cmds , rem , options ) ) {
cmds . push ( cmd ) ;
break ;
}
2019-11-19 20:48:29 +08:00
}
}
}
2020-01-20 05:29:54 +08:00
} else {
cmds . push ( [ ind , MODE _BREAK , _doc . contents ] ) ;
2019-11-19 20:48:29 +08:00
}
}
2020-01-20 05:29:54 +08:00
break ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
}
if ( _doc . id ) {
groupModeMap [ _doc . id ] = cmds [ cmds . length - 1 ] [ 1 ] ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
// Fills each line with as much code as possible before moving to a new
// line with the same indentation.
//
// Expects doc.parts to be an array of alternating content and
// whitespace. The whitespace contains the linebreaks.
//
// For example:
// ["I", line, "love", line, "monkeys"]
// or
// [{ type: group, ... }, softline, { type: group, ... }]
//
// It uses this parts structure to handle three main layout cases:
// * The first two content items fit on the same line without
// breaking
// -> output the first content item and the whitespace "flat".
// * Only the first content item fits on the line without breaking
// -> output the first content item "flat" and the whitespace with
// "break".
// * Neither content item fits on the line without breaking
// -> output the first content item and the whitespace with "break".
case "fill" :
{
var _rem = width - pos ;
var parts = _doc . parts ;
if ( parts . length === 0 ) {
2019-11-19 20:48:29 +08:00
break ;
}
2020-01-20 05:29:54 +08:00
var content = parts [ 0 ] ;
var contentFlatCmd = [ ind , MODE _FLAT , content ] ;
var contentBreakCmd = [ ind , MODE _BREAK , content ] ;
var contentFits = fits ( contentFlatCmd , [ ] , _rem , options , true ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( parts . length === 1 ) {
if ( contentFits ) {
cmds . push ( contentFlatCmd ) ;
} else {
cmds . push ( contentBreakCmd ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
var whitespace = parts [ 1 ] ;
var whitespaceFlatCmd = [ ind , MODE _FLAT , whitespace ] ;
var whitespaceBreakCmd = [ ind , MODE _BREAK , whitespace ] ;
if ( parts . length === 2 ) {
if ( contentFits ) {
cmds . push ( whitespaceFlatCmd ) ;
cmds . push ( contentFlatCmd ) ;
} else {
cmds . push ( whitespaceBreakCmd ) ;
cmds . push ( contentBreakCmd ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
} // At this point we've handled the first pair (context, separator)
// and will create a new fill doc for the rest of the content.
// Ideally we wouldn't mutate the array here but coping all the
// elements to a new array would make this algorithm quadratic,
// which is unusable for large arrays (e.g. large texts in JSX).
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
parts . splice ( 0 , 2 ) ;
var remainingCmd = [ ind , mode , fill$1 ( parts ) ] ;
var secondContent = parts [ 0 ] ;
var firstAndSecondContentFlatCmd = [ ind , MODE _FLAT , concat$1 ( [ content , whitespace , secondContent ] ) ] ;
var firstAndSecondContentFits = fits ( firstAndSecondContentFlatCmd , [ ] , _rem , options , true ) ;
if ( firstAndSecondContentFits ) {
cmds . push ( remainingCmd ) ;
2019-11-19 20:48:29 +08:00
cmds . push ( whitespaceFlatCmd ) ;
cmds . push ( contentFlatCmd ) ;
2020-01-20 05:29:54 +08:00
} else if ( contentFits ) {
cmds . push ( remainingCmd ) ;
cmds . push ( whitespaceBreakCmd ) ;
cmds . push ( contentFlatCmd ) ;
2019-11-19 20:48:29 +08:00
} else {
2020-01-20 05:29:54 +08:00
cmds . push ( remainingCmd ) ;
2019-11-19 20:48:29 +08:00
cmds . push ( whitespaceBreakCmd ) ;
cmds . push ( contentBreakCmd ) ;
}
break ;
}
2020-01-20 05:29:54 +08:00
case "if-break" :
{
var groupMode = _doc . groupId ? groupModeMap [ _doc . groupId ] : mode ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( groupMode === MODE _BREAK ) {
if ( _doc . breakContents ) {
cmds . push ( [ ind , mode , _doc . breakContents ] ) ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
if ( groupMode === MODE _FLAT ) {
if ( _doc . flatContents ) {
cmds . push ( [ ind , mode , _doc . flatContents ] ) ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
break ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
case "line-suffix" :
lineSuffix . push ( [ ind , mode , _doc . contents ] ) ;
2019-11-19 20:48:29 +08:00
break ;
2020-01-20 05:29:54 +08:00
case "line-suffix-boundary" :
if ( lineSuffix . length > 0 ) {
cmds . push ( [ ind , mode , {
type : "line" ,
hard : true
} ] ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case "line" :
switch ( mode ) {
case MODE _FLAT :
if ( ! _doc . hard ) {
if ( ! _doc . soft ) {
out . push ( " " ) ;
pos += 1 ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
} else {
// This line was forced into the output even if we
// were in flattened mode, so we need to tell the next
// group that no matter what, it needs to remeasure
// because the previous measurement didn't accurately
// capture the entire expression (this is necessary
// for nested groups)
shouldRemeasure = true ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
// fallthrough
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
case MODE _BREAK :
if ( lineSuffix . length ) {
cmds . push ( [ ind , mode , _doc ] ) ;
[ ] . push . apply ( cmds , lineSuffix . reverse ( ) ) ;
lineSuffix = [ ] ;
break ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( _doc . literal ) {
if ( ind . root ) {
out . push ( newLine , ind . root . value ) ;
pos = ind . root . length ;
} else {
out . push ( newLine ) ;
pos = 0 ;
}
2019-11-19 20:48:29 +08:00
} else {
2020-01-20 05:29:54 +08:00
pos -= trim$1 ( out ) ;
out . push ( newLine + ind . value ) ;
pos = ind . length ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
break ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
break ;
}
2019-11-19 20:48:29 +08:00
}
}
2020-01-20 05:29:54 +08:00
var cursorPlaceholderIndex = out . indexOf ( cursor$1 . placeholder ) ;
if ( cursorPlaceholderIndex !== - 1 ) {
var otherCursorPlaceholderIndex = out . indexOf ( cursor$1 . placeholder , cursorPlaceholderIndex + 1 ) ;
var beforeCursor = out . slice ( 0 , cursorPlaceholderIndex ) . join ( "" ) ;
var aroundCursor = out . slice ( cursorPlaceholderIndex + 1 , otherCursorPlaceholderIndex ) . join ( "" ) ;
var afterCursor = out . slice ( otherCursorPlaceholderIndex + 1 ) . join ( "" ) ;
return {
formatted : beforeCursor + aroundCursor + afterCursor ,
cursorNodeStart : beforeCursor . length ,
cursorNodeText : aroundCursor
} ;
}
2019-11-19 20:48:29 +08:00
return {
2020-01-20 05:29:54 +08:00
formatted : out . join ( "" )
2019-11-19 20:48:29 +08:00
} ;
}
2020-01-20 05:29:54 +08:00
var docPrinter = {
printDocToString : printDocToString
2019-11-19 20:48:29 +08:00
} ;
2020-01-20 05:29:54 +08:00
var traverseDocOnExitStackMarker = { } ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function traverseDoc ( doc , onEnter , onExit , shouldTraverseConditionalGroups ) {
var docsStack = [ doc ] ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
while ( docsStack . length !== 0 ) {
var _doc = docsStack . pop ( ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( _doc === traverseDocOnExitStackMarker ) {
onExit ( docsStack . pop ( ) ) ;
continue ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var shouldRecurse = true ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( onEnter ) {
if ( onEnter ( _doc ) === false ) {
shouldRecurse = false ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
if ( onExit ) {
docsStack . push ( _doc ) ;
docsStack . push ( traverseDocOnExitStackMarker ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( shouldRecurse ) {
// When there are multiple parts to process,
// the parts need to be pushed onto the stack in reverse order,
// so that they are processed in the original order
// when the stack is popped.
if ( _doc . type === "concat" || _doc . type === "fill" ) {
for ( var ic = _doc . parts . length , i = ic - 1 ; i >= 0 ; -- i ) {
docsStack . push ( _doc . parts [ i ] ) ;
}
} else if ( _doc . type === "if-break" ) {
if ( _doc . flatContents ) {
docsStack . push ( _doc . flatContents ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( _doc . breakContents ) {
docsStack . push ( _doc . breakContents ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
} else if ( _doc . type === "group" && _doc . expandedStates ) {
if ( shouldTraverseConditionalGroups ) {
for ( var _ic = _doc . expandedStates . length , _i = _ic - 1 ; _i >= 0 ; -- _i ) {
docsStack . push ( _doc . expandedStates [ _i ] ) ;
}
} else {
docsStack . push ( _doc . contents ) ;
}
} else if ( _doc . contents ) {
2019-11-19 20:48:29 +08:00
docsStack . push ( _doc . contents ) ;
}
}
}
}
2020-01-20 05:29:54 +08:00
function mapDoc ( doc , cb ) {
if ( doc . type === "concat" || doc . type === "fill" ) {
var parts = doc . parts . map ( function ( part ) {
return mapDoc ( part , cb ) ;
} ) ;
return cb ( Object . assign ( { } , doc , {
parts : parts
} ) ) ;
} else if ( doc . type === "if-break" ) {
var breakContents = doc . breakContents && mapDoc ( doc . breakContents , cb ) ;
var flatContents = doc . flatContents && mapDoc ( doc . flatContents , cb ) ;
return cb ( Object . assign ( { } , doc , {
breakContents : breakContents ,
flatContents : flatContents
} ) ) ;
} else if ( doc . contents ) {
var contents = mapDoc ( doc . contents , cb ) ;
return cb ( Object . assign ( { } , doc , {
contents : contents
} ) ) ;
}
return cb ( doc ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function findInDoc ( doc , fn , defaultValue ) {
var result = defaultValue ;
var hasStopped = false ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function findInDocOnEnterFn ( doc ) {
var maybeResult = fn ( doc ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( maybeResult !== undefined ) {
hasStopped = true ;
result = maybeResult ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( hasStopped ) {
return false ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
traverseDoc ( doc , findInDocOnEnterFn ) ;
return result ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function isEmpty ( n ) {
return typeof n === "string" && n . length === 0 ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function isLineNextFn ( doc ) {
if ( typeof doc === "string" ) {
return false ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "line" ) {
return true ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function isLineNext ( doc ) {
return findInDoc ( doc , isLineNextFn , false ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function willBreakFn ( doc ) {
if ( doc . type === "group" && doc . break ) {
return true ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "line" && doc . hard ) {
return true ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "break-parent" ) {
return true ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function willBreak ( doc ) {
return findInDoc ( doc , willBreakFn , false ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function breakParentGroup ( groupStack ) {
if ( groupStack . length > 0 ) {
var parentGroup = groupStack [ groupStack . length - 1 ] ; // Breaks are not propagated through conditional groups because
// the user is expected to manually handle what breaks.
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( ! parentGroup . expandedStates ) {
parentGroup . break = true ;
}
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
return null ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function propagateBreaks ( doc ) {
var alreadyVisitedSet = new Set ( ) ;
var groupStack = [ ] ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function propagateBreaksOnEnterFn ( doc ) {
if ( doc . type === "break-parent" ) {
breakParentGroup ( groupStack ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "group" ) {
groupStack . push ( doc ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( alreadyVisitedSet . has ( doc ) ) {
return false ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
alreadyVisitedSet . add ( doc ) ;
2019-11-19 20:48:29 +08:00
}
}
2020-01-20 05:29:54 +08:00
function propagateBreaksOnExitFn ( doc ) {
if ( doc . type === "group" ) {
var group = groupStack . pop ( ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( group . break ) {
breakParentGroup ( groupStack ) ;
}
2019-11-19 20:48:29 +08:00
}
}
2020-01-20 05:29:54 +08:00
traverseDoc ( doc , propagateBreaksOnEnterFn , propagateBreaksOnExitFn ,
/* shouldTraverseConditionalGroups */
true ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function removeLinesFn ( doc ) {
// Force this doc into flat mode by statically converting all
// lines into spaces (or soft lines into nothing). Hard lines
// should still output because there's too great of a chance
// of breaking existing assumptions otherwise.
if ( doc . type === "line" && ! doc . hard ) {
return doc . soft ? "" : " " ;
} else if ( doc . type === "if-break" ) {
return doc . flatContents || "" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return doc ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function removeLines ( doc ) {
return mapDoc ( doc , removeLinesFn ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function stripTrailingHardline ( doc ) {
// HACK remove ending hardline, original PR: #1984
if ( doc . type === "concat" && doc . parts . length !== 0 ) {
var lastPart = doc . parts [ doc . parts . length - 1 ] ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( lastPart . type === "concat" ) {
if ( lastPart . parts . length === 2 && lastPart . parts [ 0 ] . hard && lastPart . parts [ 1 ] . type === "break-parent" ) {
return {
type : "concat" ,
parts : doc . parts . slice ( 0 , - 1 )
} ;
}
2019-11-19 20:48:29 +08:00
return {
type : "concat" ,
2020-01-20 05:29:54 +08:00
parts : doc . parts . slice ( 0 , - 1 ) . concat ( stripTrailingHardline ( lastPart ) )
2019-11-19 20:48:29 +08:00
} ;
}
}
2020-01-20 05:29:54 +08:00
return doc ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var docUtils = {
isEmpty : isEmpty ,
willBreak : willBreak ,
isLineNext : isLineNext ,
traverseDoc : traverseDoc ,
findInDoc : findInDoc ,
mapDoc : mapDoc ,
propagateBreaks : propagateBreaks ,
removeLines : removeLines ,
stripTrailingHardline : stripTrailingHardline
} ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
function flattenDoc ( doc ) {
if ( doc . type === "concat" ) {
var res = [ ] ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
for ( var i = 0 ; i < doc . parts . length ; ++ i ) {
var doc2 = doc . parts [ i ] ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( typeof doc2 !== "string" && doc2 . type === "concat" ) {
[ ] . push . apply ( res , flattenDoc ( doc2 ) . parts ) ;
} else {
var flattened = flattenDoc ( doc2 ) ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( flattened !== "" ) {
res . push ( flattened ) ;
}
2019-11-19 20:48:29 +08:00
}
}
2020-01-20 05:29:54 +08:00
return Object . assign ( { } , doc , {
parts : res
} ) ;
} else if ( doc . type === "if-break" ) {
return Object . assign ( { } , doc , {
breakContents : doc . breakContents != null ? flattenDoc ( doc . breakContents ) : null ,
flatContents : doc . flatContents != null ? flattenDoc ( doc . flatContents ) : null
} ) ;
} else if ( doc . type === "group" ) {
return Object . assign ( { } , doc , {
contents : flattenDoc ( doc . contents ) ,
expandedStates : doc . expandedStates ? doc . expandedStates . map ( flattenDoc ) : doc . expandedStates
} ) ;
} else if ( doc . contents ) {
return Object . assign ( { } , doc , {
contents : flattenDoc ( doc . contents )
} ) ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return doc ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
function printDoc ( doc ) {
if ( typeof doc === "string" ) {
return JSON . stringify ( doc ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
if ( doc . type === "line" ) {
if ( doc . literal ) {
return "literalline" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . hard ) {
return "hardline" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . soft ) {
return "softline" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return "line" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "break-parent" ) {
return "breakParent" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "trim" ) {
return "trim" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "concat" ) {
return "[" + doc . parts . map ( printDoc ) . join ( ", " ) + "]" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "indent" ) {
return "indent(" + printDoc ( doc . contents ) + ")" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "align" ) {
return doc . n === - Infinity ? "dedentToRoot(" + printDoc ( doc . contents ) + ")" : doc . n < 0 ? "dedent(" + printDoc ( doc . contents ) + ")" : doc . n . type === "root" ? "markAsRoot(" + printDoc ( doc . contents ) + ")" : "align(" + JSON . stringify ( doc . n ) + ", " + printDoc ( doc . contents ) + ")" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "if-break" ) {
return "ifBreak(" + printDoc ( doc . breakContents ) + ( doc . flatContents ? ", " + printDoc ( doc . flatContents ) : "" ) + ")" ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
if ( doc . type === "group" ) {
if ( doc . expandedStates ) {
return "conditionalGroup(" + "[" + doc . expandedStates . map ( printDoc ) . join ( "," ) + "])" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
return ( doc . break ? "wrappedGroup" : "group" ) + "(" + printDoc ( doc . contents ) + ")" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "fill" ) {
return "fill" + "(" + doc . parts . map ( printDoc ) . join ( ", " ) + ")" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "line-suffix" ) {
return "lineSuffix(" + printDoc ( doc . contents ) + ")" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
if ( doc . type === "line-suffix-boundary" ) {
return "lineSuffixBoundary" ;
}
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
throw new Error ( "Unknown doc type " + doc . type ) ;
2019-11-19 20:48:29 +08:00
}
2020-01-20 05:29:54 +08:00
var docDebug = {
printDocToDebug : function printDocToDebug ( doc ) {
return printDoc ( flattenDoc ( doc ) ) ;
}
} ;
2019-11-19 20:48:29 +08:00
2020-01-20 05:29:54 +08:00
var doc = {
builders : docBuilders ,
printer : docPrinter ,
utils : docUtils ,
debug : docDebug
} ;
var doc _1 = doc . builders ;
var doc _2 = doc . printer ;
var doc _3 = doc . utils ;
var doc _4 = doc . debug ;
exports . builders = doc _1 ;
exports . debug = doc _4 ;
exports . default = doc ;
exports . printer = doc _2 ;
exports . utils = doc _3 ;
Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
2019-11-19 20:48:29 +08:00
} ) ) ) ;