index.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.extract = extract;
  6. exports.strip = strip;
  7. exports.parse = parse;
  8. exports.parseWithComments = parseWithComments;
  9. exports.print = print;
  10. function _os() {
  11. const data = require('os');
  12. _os = function _os() {
  13. return data;
  14. };
  15. return data;
  16. }
  17. function _detectNewline() {
  18. const data = _interopRequireDefault(require('detect-newline'));
  19. _detectNewline = function _detectNewline() {
  20. return data;
  21. };
  22. return data;
  23. }
  24. function _interopRequireDefault(obj) {
  25. return obj && obj.__esModule ? obj : {default: obj};
  26. }
  27. /**
  28. * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  29. *
  30. * This source code is licensed under the MIT license found in the
  31. * LICENSE file in the root directory of this source tree.
  32. */
  33. const commentEndRe = /\*\/$/;
  34. const commentStartRe = /^\/\*\*/;
  35. const docblockRe = /^\s*(\/\*\*?(.|\r?\n)*?\*\/)/;
  36. const lineCommentRe = /(^|\s+)\/\/([^\r\n]*)/g;
  37. const ltrimNewlineRe = /^(\r?\n)+/;
  38. const multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *(?![^@\r\n]*\/\/[^]*)([^@\r\n\s][^@\r\n]+?) *\r?\n/g;
  39. const propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g;
  40. const stringStartRe = /(\r?\n|^) *\* ?/g;
  41. function extract(contents) {
  42. const match = contents.match(docblockRe);
  43. return match ? match[0].trimLeft() : '';
  44. }
  45. function strip(contents) {
  46. const match = contents.match(docblockRe);
  47. return match && match[0] ? contents.substring(match[0].length) : contents;
  48. }
  49. function parse(docblock) {
  50. return parseWithComments(docblock).pragmas;
  51. }
  52. function parseWithComments(docblock) {
  53. const line = (0, _detectNewline().default)(docblock) || _os().EOL;
  54. docblock = docblock
  55. .replace(commentStartRe, '')
  56. .replace(commentEndRe, '')
  57. .replace(stringStartRe, '$1'); // Normalize multi-line directives
  58. let prev = '';
  59. while (prev !== docblock) {
  60. prev = docblock;
  61. docblock = docblock.replace(multilineRe, `${line}$1 $2${line}`);
  62. }
  63. docblock = docblock.replace(ltrimNewlineRe, '').trimRight();
  64. const result = Object.create(null);
  65. const comments = docblock
  66. .replace(propertyRe, '')
  67. .replace(ltrimNewlineRe, '')
  68. .trimRight();
  69. let match;
  70. while ((match = propertyRe.exec(docblock))) {
  71. // strip linecomments from pragmas
  72. const nextPragma = match[2].replace(lineCommentRe, '');
  73. if (
  74. typeof result[match[1]] === 'string' ||
  75. Array.isArray(result[match[1]])
  76. ) {
  77. result[match[1]] = [].concat(result[match[1]], nextPragma);
  78. } else {
  79. result[match[1]] = nextPragma;
  80. }
  81. }
  82. return {
  83. comments,
  84. pragmas: result
  85. };
  86. }
  87. function print({comments = '', pragmas = {}}) {
  88. const line = (0, _detectNewline().default)(comments) || _os().EOL;
  89. const head = '/**';
  90. const start = ' *';
  91. const tail = ' */';
  92. const keys = Object.keys(pragmas);
  93. const printedObject = keys
  94. .map(key => printKeyValues(key, pragmas[key]))
  95. .reduce((arr, next) => arr.concat(next), [])
  96. .map(keyValue => start + ' ' + keyValue + line)
  97. .join('');
  98. if (!comments) {
  99. if (keys.length === 0) {
  100. return '';
  101. }
  102. if (keys.length === 1 && !Array.isArray(pragmas[keys[0]])) {
  103. const value = pragmas[keys[0]];
  104. return `${head} ${printKeyValues(keys[0], value)[0]}${tail}`;
  105. }
  106. }
  107. const printedComments =
  108. comments
  109. .split(line)
  110. .map(textLine => `${start} ${textLine}`)
  111. .join(line) + line;
  112. return (
  113. head +
  114. line +
  115. (comments ? printedComments : '') +
  116. (comments && keys.length ? start + line : '') +
  117. printedObject +
  118. tail
  119. );
  120. }
  121. function printKeyValues(key, valueOrArray) {
  122. return [].concat(valueOrArray).map(value => `@${key} ${value}`.trim());
  123. }