.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / pretty-format / build / index.js
1 'use strict';
2
3 var _ansiStyles = require('ansi-styles');
4
5 var _ansiStyles2 = _interopRequireDefault(_ansiStyles);
6
7 var _collections = require('./collections');
8
9 var _asymmetric_matcher = require('./plugins/asymmetric_matcher');
10
11 var _asymmetric_matcher2 = _interopRequireDefault(_asymmetric_matcher);
12
13 var _convert_ansi = require('./plugins/convert_ansi');
14
15 var _convert_ansi2 = _interopRequireDefault(_convert_ansi);
16
17 var _dom_collection = require('./plugins/dom_collection');
18
19 var _dom_collection2 = _interopRequireDefault(_dom_collection);
20
21 var _dom_element = require('./plugins/dom_element');
22
23 var _dom_element2 = _interopRequireDefault(_dom_element);
24
25 var _immutable = require('./plugins/immutable');
26
27 var _immutable2 = _interopRequireDefault(_immutable);
28
29 var _react_element = require('./plugins/react_element');
30
31 var _react_element2 = _interopRequireDefault(_react_element);
32
33 var _react_test_component = require('./plugins/react_test_component');
34
35 var _react_test_component2 = _interopRequireDefault(_react_test_component);
36
37 function _interopRequireDefault(obj) {
38   return obj && obj.__esModule ? obj : {default: obj};
39 }
40
41 /**
42  * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
43  *
44  * This source code is licensed under the MIT license found in the
45  * LICENSE file in the root directory of this source tree.
46  *
47  *
48  */
49
50 const toString = Object.prototype.toString;
51 const toISOString = Date.prototype.toISOString;
52 const errorToString = Error.prototype.toString;
53 const regExpToString = RegExp.prototype.toString;
54 const symbolToString = Symbol.prototype.toString;
55
56 // Explicitly comparing typeof constructor to function avoids undefined as name
57 // when mock identity-obj-proxy returns the key as the value for any key.
58 const getConstructorName = val =>
59   (typeof val.constructor === 'function' && val.constructor.name) || 'Object';
60
61 // Is val is equal to global window object? Works even if it does not exist :)
62 /* global window */
63 const isWindow = val => typeof window !== 'undefined' && val === window;
64
65 const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/;
66 const NEWLINE_REGEXP = /\n/gi;
67
68 class PrettyFormatPluginError extends Error {
69   constructor(message, stack) {
70     super(message);
71     this.stack = stack;
72     this.name = this.constructor.name;
73   }
74 }
75
76 function isToStringedArrayType(toStringed) {
77   return (
78     toStringed === '[object Array]' ||
79     toStringed === '[object ArrayBuffer]' ||
80     toStringed === '[object DataView]' ||
81     toStringed === '[object Float32Array]' ||
82     toStringed === '[object Float64Array]' ||
83     toStringed === '[object Int8Array]' ||
84     toStringed === '[object Int16Array]' ||
85     toStringed === '[object Int32Array]' ||
86     toStringed === '[object Uint8Array]' ||
87     toStringed === '[object Uint8ClampedArray]' ||
88     toStringed === '[object Uint16Array]' ||
89     toStringed === '[object Uint32Array]'
90   );
91 }
92
93 function printNumber(val) {
94   return Object.is(val, -0) ? '-0' : String(val);
95 }
96
97 function printFunction(val, printFunctionName) {
98   if (!printFunctionName) {
99     return '[Function]';
100   }
101   return '[Function ' + (val.name || 'anonymous') + ']';
102 }
103
104 function printSymbol(val) {
105   return symbolToString.call(val).replace(SYMBOL_REGEXP, 'Symbol($1)');
106 }
107
108 function printError(val) {
109   return '[' + errorToString.call(val) + ']';
110 }
111
112 function printBasicValue(val, printFunctionName, escapeRegex) {
113   if (val === true || val === false) {
114     return '' + val;
115   }
116   if (val === undefined) {
117     return 'undefined';
118   }
119   if (val === null) {
120     return 'null';
121   }
122
123   const typeOf = typeof val;
124
125   if (typeOf === 'number') {
126     return printNumber(val);
127   }
128   if (typeOf === 'string') {
129     return '"' + val.replace(/"|\\/g, '\\$&') + '"';
130   }
131   if (typeOf === 'function') {
132     return printFunction(val, printFunctionName);
133   }
134   if (typeOf === 'symbol') {
135     return printSymbol(val);
136   }
137
138   const toStringed = toString.call(val);
139
140   if (toStringed === '[object WeakMap]') {
141     return 'WeakMap {}';
142   }
143   if (toStringed === '[object WeakSet]') {
144     return 'WeakSet {}';
145   }
146   if (
147     toStringed === '[object Function]' ||
148     toStringed === '[object GeneratorFunction]'
149   ) {
150     return printFunction(val, printFunctionName);
151   }
152   if (toStringed === '[object Symbol]') {
153     return printSymbol(val);
154   }
155   if (toStringed === '[object Date]') {
156     return isNaN(+val) ? 'Date { NaN }' : toISOString.call(val);
157   }
158   if (toStringed === '[object Error]') {
159     return printError(val);
160   }
161   if (toStringed === '[object RegExp]') {
162     if (escapeRegex) {
163       // https://github.com/benjamingr/RegExp.escape/blob/master/polyfill.js
164       return regExpToString.call(val).replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
165     }
166     return regExpToString.call(val);
167   }
168
169   if (val instanceof Error) {
170     return printError(val);
171   }
172
173   return null;
174 }
175
176 function printComplexValue(
177   val,
178   config,
179   indentation,
180   depth,
181   refs,
182   hasCalledToJSON
183 ) {
184   if (refs.indexOf(val) !== -1) {
185     return '[Circular]';
186   }
187   refs = refs.slice();
188   refs.push(val);
189
190   const hitMaxDepth = ++depth > config.maxDepth;
191   const min = config.min;
192
193   if (
194     config.callToJSON &&
195     !hitMaxDepth &&
196     val.toJSON &&
197     typeof val.toJSON === 'function' &&
198     !hasCalledToJSON
199   ) {
200     return printer(val.toJSON(), config, indentation, depth, refs, true);
201   }
202
203   const toStringed = toString.call(val);
204   if (toStringed === '[object Arguments]') {
205     return hitMaxDepth
206       ? '[Arguments]'
207       : (min ? '' : 'Arguments ') +
208           '[' +
209           (0, _collections.printListItems)(
210             val,
211             config,
212             indentation,
213             depth,
214             refs,
215             printer
216           ) +
217           ']';
218   }
219   if (isToStringedArrayType(toStringed)) {
220     return hitMaxDepth
221       ? '[' + val.constructor.name + ']'
222       : (min ? '' : val.constructor.name + ' ') +
223           '[' +
224           (0, _collections.printListItems)(
225             val,
226             config,
227             indentation,
228             depth,
229             refs,
230             printer
231           ) +
232           ']';
233   }
234   if (toStringed === '[object Map]') {
235     return hitMaxDepth
236       ? '[Map]'
237       : 'Map {' +
238           (0, _collections.printIteratorEntries)(
239             val.entries(),
240             config,
241             indentation,
242             depth,
243             refs,
244             printer,
245             ' => '
246           ) +
247           '}';
248   }
249   if (toStringed === '[object Set]') {
250     return hitMaxDepth
251       ? '[Set]'
252       : 'Set {' +
253           (0, _collections.printIteratorValues)(
254             val.values(),
255             config,
256             indentation,
257             depth,
258             refs,
259             printer
260           ) +
261           '}';
262   }
263
264   // Avoid failure to serialize global window object in jsdom test environment.
265   // For example, not even relevant if window is prop of React element.
266   return hitMaxDepth || isWindow(val)
267     ? '[' + getConstructorName(val) + ']'
268     : (min ? '' : getConstructorName(val) + ' ') +
269         '{' +
270         (0, _collections.printObjectProperties)(
271           val,
272           config,
273           indentation,
274           depth,
275           refs,
276           printer
277         ) +
278         '}';
279 }
280
281 function printPlugin(plugin, val, config, indentation, depth, refs) {
282   let printed;
283
284   try {
285     printed = plugin.serialize
286       ? plugin.serialize(val, config, indentation, depth, refs, printer)
287       : plugin.print(
288           val,
289           valChild => printer(valChild, config, indentation, depth, refs),
290           str => {
291             const indentationNext = indentation + config.indent;
292             return (
293               indentationNext +
294               str.replace(NEWLINE_REGEXP, '\n' + indentationNext)
295             );
296           },
297           {
298             edgeSpacing: config.spacingOuter,
299             min: config.min,
300             spacing: config.spacingInner
301           },
302           config.colors
303         );
304   } catch (error) {
305     throw new PrettyFormatPluginError(error.message, error.stack);
306   }
307   if (typeof printed !== 'string') {
308     throw new Error(
309       `pretty-format: Plugin must return type "string" but instead returned "${typeof printed}".`
310     );
311   }
312   return printed;
313 }
314
315 function findPlugin(plugins, val) {
316   for (let p = 0; p < plugins.length; p++) {
317     try {
318       if (plugins[p].test(val)) {
319         return plugins[p];
320       }
321     } catch (error) {
322       throw new PrettyFormatPluginError(error.message, error.stack);
323     }
324   }
325
326   return null;
327 }
328
329 function printer(val, config, indentation, depth, refs, hasCalledToJSON) {
330   const plugin = findPlugin(config.plugins, val);
331   if (plugin !== null) {
332     return printPlugin(plugin, val, config, indentation, depth, refs);
333   }
334
335   const basicResult = printBasicValue(
336     val,
337     config.printFunctionName,
338     config.escapeRegex
339   );
340   if (basicResult !== null) {
341     return basicResult;
342   }
343
344   return printComplexValue(
345     val,
346     config,
347     indentation,
348     depth,
349     refs,
350     hasCalledToJSON
351   );
352 }
353
354 const DEFAULT_THEME = {
355   comment: 'gray',
356   content: 'reset',
357   prop: 'yellow',
358   tag: 'cyan',
359   value: 'green'
360 };
361
362 const DEFAULT_THEME_KEYS = Object.keys(DEFAULT_THEME);
363
364 const DEFAULT_OPTIONS = {
365   callToJSON: true,
366   escapeRegex: false,
367   highlight: false,
368   indent: 2,
369   maxDepth: Infinity,
370   min: false,
371   plugins: [],
372   printFunctionName: true,
373   theme: DEFAULT_THEME
374 };
375
376 function validateOptions(options) {
377   Object.keys(options).forEach(key => {
378     if (!DEFAULT_OPTIONS.hasOwnProperty(key)) {
379       throw new Error(`pretty-format: Unknown option "${key}".`);
380     }
381   });
382
383   if (options.min && options.indent !== undefined && options.indent !== 0) {
384     throw new Error(
385       'pretty-format: Options "min" and "indent" cannot be used together.'
386     );
387   }
388
389   if (options.theme !== undefined) {
390     if (options.theme === null) {
391       throw new Error(`pretty-format: Option "theme" must not be null.`);
392     }
393
394     if (typeof options.theme !== 'object') {
395       throw new Error(
396         `pretty-format: Option "theme" must be of type "object" but instead received "${typeof options.theme}".`
397       );
398     }
399   }
400 }
401
402 const getColorsHighlight = (
403   options
404   // $FlowFixMe: Flow thinks keys from `Colors` are missing from `DEFAULT_THEME_KEYS`
405 ) =>
406   DEFAULT_THEME_KEYS.reduce((colors, key) => {
407     const value =
408       options.theme && options.theme[key] !== undefined
409         ? options.theme[key]
410         : DEFAULT_THEME[key];
411     const color = _ansiStyles2.default[value];
412     if (
413       color &&
414       typeof color.close === 'string' &&
415       typeof color.open === 'string'
416     ) {
417       colors[key] = color;
418     } else {
419       throw new Error(
420         `pretty-format: Option "theme" has a key "${key}" whose value "${value}" is undefined in ansi-styles.`
421       );
422     }
423     return colors;
424   }, Object.create(null));
425
426 const getColorsEmpty = () =>
427   // $FlowFixMe: Flow thinks keys from `Colors` are missing from `DEFAULT_THEME_KEYS`
428   DEFAULT_THEME_KEYS.reduce((colors, key) => {
429     colors[key] = {close: '', open: ''};
430     return colors;
431   }, Object.create(null));
432
433 const getPrintFunctionName = options =>
434   options && options.printFunctionName !== undefined
435     ? options.printFunctionName
436     : DEFAULT_OPTIONS.printFunctionName;
437
438 const getEscapeRegex = options =>
439   options && options.escapeRegex !== undefined
440     ? options.escapeRegex
441     : DEFAULT_OPTIONS.escapeRegex;
442
443 const getConfig = options => ({
444   callToJSON:
445     options && options.callToJSON !== undefined
446       ? options.callToJSON
447       : DEFAULT_OPTIONS.callToJSON,
448   colors:
449     options && options.highlight
450       ? getColorsHighlight(options)
451       : getColorsEmpty(),
452   escapeRegex: getEscapeRegex(options),
453   indent:
454     options && options.min
455       ? ''
456       : createIndent(
457           options && options.indent !== undefined
458             ? options.indent
459             : DEFAULT_OPTIONS.indent
460         ),
461   maxDepth:
462     options && options.maxDepth !== undefined
463       ? options.maxDepth
464       : DEFAULT_OPTIONS.maxDepth,
465   min: options && options.min !== undefined ? options.min : DEFAULT_OPTIONS.min,
466   plugins:
467     options && options.plugins !== undefined
468       ? options.plugins
469       : DEFAULT_OPTIONS.plugins,
470   printFunctionName: getPrintFunctionName(options),
471   spacingInner: options && options.min ? ' ' : '\n',
472   spacingOuter: options && options.min ? '' : '\n'
473 });
474
475 function createIndent(indent) {
476   return new Array(indent + 1).join(' ');
477 }
478
479 function prettyFormat(val, options) {
480   if (options) {
481     validateOptions(options);
482     if (options.plugins) {
483       const plugin = findPlugin(options.plugins, val);
484       if (plugin !== null) {
485         return printPlugin(plugin, val, getConfig(options), '', 0, []);
486       }
487     }
488   }
489
490   const basicResult = printBasicValue(
491     val,
492     getPrintFunctionName(options),
493     getEscapeRegex(options)
494   );
495   if (basicResult !== null) {
496     return basicResult;
497   }
498
499   return printComplexValue(val, getConfig(options), '', 0, []);
500 }
501
502 prettyFormat.plugins = {
503   AsymmetricMatcher: _asymmetric_matcher2.default,
504   ConvertAnsi: _convert_ansi2.default,
505   DOMCollection: _dom_collection2.default,
506   DOMElement: _dom_element2.default,
507   Immutable: _immutable2.default,
508   ReactElement: _react_element2.default,
509   ReactTestComponent: _react_test_component2.default
510 };
511
512 module.exports = prettyFormat;