| | |
| | | // multiline comment |
| | | return ( |
| | | (comment.type === "comment2" || comment.type === "comment1") |
| | | && /@preserve|@lic|@cc_on|^\**!/i.test(comment.value) |
| | | && /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value) |
| | | ); |
| | | } |
| | | |
| | | class Rope { |
| | | constructor() { |
| | | this.committed = ""; |
| | | this.current = ""; |
| | | } |
| | | |
| | | append(str) { |
| | | this.current += str; |
| | | } |
| | | |
| | | insertAt(char, index) { |
| | | const { committed, current } = this; |
| | | if (index < committed.length) { |
| | | this.committed = committed.slice(0, index) + char + committed.slice(index); |
| | | } else if (index === committed.length) { |
| | | this.committed += char; |
| | | } else { |
| | | index -= committed.length; |
| | | this.committed += current.slice(0, index) + char; |
| | | this.current = current.slice(index); |
| | | } |
| | | } |
| | | |
| | | charAt(index) { |
| | | const { committed } = this; |
| | | if (index < committed.length) return committed[index]; |
| | | return this.current[index - committed.length]; |
| | | } |
| | | |
| | | curLength() { |
| | | return this.current.length; |
| | | } |
| | | |
| | | length() { |
| | | return this.committed.length + this.current.length; |
| | | } |
| | | |
| | | toString() { |
| | | return this.committed + this.current; |
| | | } |
| | | } |
| | | |
| | | function OutputStream(options) { |
| | |
| | | var current_col = 0; |
| | | var current_line = 1; |
| | | var current_pos = 0; |
| | | var OUTPUT = ""; |
| | | var OUTPUT = new Rope(); |
| | | let printed_comments = new Set(); |
| | | |
| | | var to_utf8 = options.ascii_only ? function(str, identifier) { |
| | | if (options.ecma >= 2015 && !options.safari10) { |
| | | var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) { |
| | | if (options.ecma >= 2015 && !options.safari10 && !regexp) { |
| | | str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) { |
| | | var code = get_full_char_code(ch, 0).toString(16); |
| | | return "\\u{" + code + "}"; |
| | |
| | | var ensure_line_len = options.max_line_len ? function() { |
| | | if (current_col > options.max_line_len) { |
| | | if (might_add_newline) { |
| | | var left = OUTPUT.slice(0, might_add_newline); |
| | | var right = OUTPUT.slice(might_add_newline); |
| | | OUTPUT.insertAt("\n", might_add_newline); |
| | | const curLength = OUTPUT.curLength(); |
| | | if (mappings) { |
| | | var delta = right.length - current_col; |
| | | var delta = curLength - current_col; |
| | | mappings.forEach(function(mapping) { |
| | | mapping.line++; |
| | | mapping.col += delta; |
| | | }); |
| | | } |
| | | OUTPUT = left + "\n" + right; |
| | | current_line++; |
| | | current_pos++; |
| | | current_col = right.length; |
| | | current_col = curLength; |
| | | } |
| | | } |
| | | if (might_add_newline) { |
| | |
| | | |
| | | if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") { |
| | | if (options.semicolons || requireSemicolonChars.has(ch)) { |
| | | OUTPUT += ";"; |
| | | OUTPUT.append(";"); |
| | | current_col++; |
| | | current_pos++; |
| | | } else { |
| | | ensure_line_len(); |
| | | if (current_col > 0) { |
| | | OUTPUT += "\n"; |
| | | OUTPUT.append("\n"); |
| | | current_pos++; |
| | | current_line++; |
| | | current_col = 0; |
| | |
| | | || (ch == "/" && ch == prev) |
| | | || ((ch == "+" || ch == "-") && ch == last) |
| | | ) { |
| | | OUTPUT += " "; |
| | | OUTPUT.append(" "); |
| | | current_col++; |
| | | current_pos++; |
| | | } |
| | |
| | | if (!might_add_newline) do_add_mapping(); |
| | | } |
| | | |
| | | OUTPUT += str; |
| | | OUTPUT.append(str); |
| | | has_parens = str[str.length - 1] == "("; |
| | | current_pos += str.length; |
| | | var a = str.split(/\r?\n/), n = a.length - 1; |
| | |
| | | |
| | | var newline = options.beautify ? function() { |
| | | if (newline_insert < 0) return print("\n"); |
| | | if (OUTPUT[newline_insert] != "\n") { |
| | | OUTPUT = OUTPUT.slice(0, newline_insert) + "\n" + OUTPUT.slice(newline_insert); |
| | | if (OUTPUT.charAt(newline_insert) != "\n") { |
| | | OUTPUT.insertAt("\n", newline_insert); |
| | | current_pos++; |
| | | current_line++; |
| | | } |
| | | newline_insert++; |
| | | } : options.max_line_len ? function() { |
| | | ensure_line_len(); |
| | | might_add_newline = OUTPUT.length; |
| | | might_add_newline = OUTPUT.length(); |
| | | } : noop; |
| | | |
| | | var semicolon = options.beautify ? function() { |
| | |
| | | if (might_add_newline) { |
| | | ensure_line_len(); |
| | | } |
| | | return OUTPUT; |
| | | return OUTPUT.toString(); |
| | | } |
| | | |
| | | function has_nlb() { |
| | | let n = OUTPUT.length - 1; |
| | | const output = OUTPUT.toString(); |
| | | let n = output.length - 1; |
| | | while (n >= 0) { |
| | | const code = OUTPUT.charCodeAt(n); |
| | | const code = output.charCodeAt(n); |
| | | if (code === CODE_LINE_BREAK) { |
| | | return true; |
| | | } |
| | |
| | | !/comment[134]/.test(c.type) |
| | | ))) return; |
| | | printed_comments.add(comments); |
| | | var insert = OUTPUT.length; |
| | | var insert = OUTPUT.length(); |
| | | comments.filter(comment_filter, node).forEach(function(c, i) { |
| | | if (printed_comments.has(c)) return; |
| | | printed_comments.add(c); |
| | |
| | | need_space = true; |
| | | } |
| | | }); |
| | | if (OUTPUT.length > insert) newline_insert = insert; |
| | | if (OUTPUT.length() > insert) newline_insert = insert; |
| | | } |
| | | |
| | | var stack = []; |
| | |
| | | var encoded = encode_string(str, quote); |
| | | if (escape_directive === true && !encoded.includes("\\")) { |
| | | // Insert semicolons to break directive prologue |
| | | if (!EXPECT_DIRECTIVE.test(OUTPUT)) { |
| | | if (!EXPECT_DIRECTIVE.test(OUTPUT.toString())) { |
| | | force_semicolon(); |
| | | } |
| | | force_semicolon(); |
| | |
| | | var p = output.parent(); |
| | | if (this.args.length === 0 |
| | | && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]() |
| | | || p instanceof AST_Call && p.expression === this)) // (new foo)(bar) |
| | | || p instanceof AST_Call && p.expression === this |
| | | || p instanceof AST_PrefixedTemplateString && p.prefix === this)) // (new foo)(bar) |
| | | return true; |
| | | }); |
| | | |
| | |
| | | output.space(); |
| | | } |
| | | self.module_name.print(output); |
| | | if (self.assert_clause) { |
| | | output.print("assert"); |
| | | self.assert_clause.print(output); |
| | | } |
| | | output.semicolon(); |
| | | }); |
| | | DEFPRINT(AST_ImportMeta, function(self, output) { |
| | |
| | | output.print("from"); |
| | | output.space(); |
| | | self.module_name.print(output); |
| | | } |
| | | if (self.assert_clause) { |
| | | output.print("assert"); |
| | | self.assert_clause.print(output); |
| | | } |
| | | if (self.exported_value |
| | | && !(self.exported_value instanceof AST_Defun || |
| | |
| | | flags = flags ? sort_regexp_flags(flags) : ""; |
| | | source = source.replace(r_slash_script, slash_script_replace); |
| | | |
| | | output.print(output.to_utf8(`/${source}/${flags}`)); |
| | | output.print(output.to_utf8(`/${source}/${flags}`, false, true)); |
| | | |
| | | const parent = output.parent(); |
| | | if ( |