版博士V2.0程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

227 lines
7.7 KiB

  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.mapLinesColumns = exports.generateMessageFunction = exports.createCodeGenerator = void 0;
  4. const message_compiler_1 = require("@intlify/message-compiler");
  5. const source_map_1 = require("source-map");
  6. const shared_1 = require("@intlify/shared");
  7. function createCodeGenerator(options = {
  8. filename: 'bundle.json',
  9. sourceMap: false,
  10. env: 'development',
  11. forceStringify: false
  12. }) {
  13. const { sourceMap, source, filename } = options;
  14. const _context = Object.assign({
  15. code: '',
  16. column: 1,
  17. line: 1,
  18. offset: 0,
  19. map: undefined,
  20. indentLevel: 0
  21. }, options);
  22. const context = () => _context;
  23. function push(code, node, name) {
  24. _context.code += code;
  25. if (_context.map && node) {
  26. if (node.loc && node.loc !== message_compiler_1.LocationStub) {
  27. addMapping(node.loc.start, name);
  28. }
  29. advancePositionWithSource(_context, code);
  30. }
  31. }
  32. function _newline(n) {
  33. push('\n' + ` `.repeat(n));
  34. }
  35. function indent(withNewLine = true) {
  36. const level = ++_context.indentLevel;
  37. withNewLine && _newline(level);
  38. }
  39. function deindent(withNewLine = true) {
  40. const level = --_context.indentLevel;
  41. withNewLine && _newline(level);
  42. }
  43. function newline() {
  44. _newline(_context.indentLevel);
  45. }
  46. function pushline(code, node, name) {
  47. push(code, node, name);
  48. newline();
  49. }
  50. function addMapping(loc, name) {
  51. _context.map.addMapping({
  52. name,
  53. source: _context.filename,
  54. original: {
  55. line: loc.line,
  56. column: loc.column - 1
  57. },
  58. generated: {
  59. line: _context.line,
  60. column: _context.column - 1
  61. }
  62. });
  63. }
  64. if (sourceMap && source) {
  65. _context.map = new source_map_1.SourceMapGenerator();
  66. _context.map.setSourceContent(filename, source);
  67. }
  68. return {
  69. context,
  70. push,
  71. indent,
  72. deindent,
  73. newline,
  74. pushline
  75. };
  76. }
  77. exports.createCodeGenerator = createCodeGenerator;
  78. function advancePositionWithSource(pos, source, numberOfCharacters = source.length) {
  79. if (pos.offset == null) {
  80. return pos;
  81. }
  82. let linesCount = 0;
  83. let lastNewLinePos = -1;
  84. for (let i = 0; i < numberOfCharacters; i++) {
  85. if (source.charCodeAt(i) === 10 /* newline char code */) {
  86. linesCount++;
  87. lastNewLinePos = i;
  88. }
  89. }
  90. pos.offset += numberOfCharacters;
  91. pos.line += linesCount;
  92. pos.column =
  93. lastNewLinePos === -1
  94. ? pos.column + numberOfCharacters
  95. : numberOfCharacters - lastNewLinePos;
  96. return pos;
  97. }
  98. const DETECT_MESSAGE = `Detected HTML in '{msg}' message.`;
  99. const ON_ERROR_NOOP = () => { }; // eslint-disable-line @typescript-eslint/no-empty-function
  100. function parsePath(path) {
  101. return path ? path.join('.') : '';
  102. }
  103. function generateMessageFunction(msg, options, path) {
  104. const env = options.env != null ? options.env : 'development';
  105. const strictMessage = (0, shared_1.isBoolean)(options.strictMessage)
  106. ? options.strictMessage
  107. : true;
  108. const escapeHtml = !!options.escapeHtml;
  109. const onError = options.onError || ON_ERROR_NOOP;
  110. const errors = [];
  111. let detecteHtmlInMsg = false;
  112. if ((0, message_compiler_1.detectHtmlTag)(msg)) {
  113. detecteHtmlInMsg = true;
  114. if (strictMessage) {
  115. const errMsg = (0, shared_1.format)(DETECT_MESSAGE, { msg });
  116. onError((0, shared_1.format)(errMsg), {
  117. source: msg,
  118. path: parsePath(path)
  119. });
  120. }
  121. }
  122. const _msg = detecteHtmlInMsg && escapeHtml ? (0, shared_1.escapeHtml)(msg) : msg;
  123. const newOptions = Object.assign({ mode: 'arrow' }, options);
  124. newOptions.onError = (err) => {
  125. if (onError) {
  126. const extra = {
  127. source: msg,
  128. path: parsePath(path),
  129. code: err.code,
  130. domain: err.domain,
  131. location: err.location
  132. };
  133. onError(err.message, extra);
  134. errors.push(err);
  135. }
  136. };
  137. const { code, ast, map } = (0, message_compiler_1.baseCompile)(_msg, newOptions);
  138. const occured = errors.length > 0;
  139. const genCode = !occured
  140. ? env === 'development'
  141. ? `(()=>{const fn=${code};fn.source=${JSON.stringify(msg)};return fn;})()`
  142. : `${code}`
  143. : _msg;
  144. return { code: genCode, ast, map, errors };
  145. }
  146. exports.generateMessageFunction = generateMessageFunction;
  147. function mapLinesColumns(resMap, codeMaps, inSourceMap) {
  148. if (!resMap) {
  149. return null;
  150. }
  151. const resMapConsumer = new source_map_1.SourceMapConsumer(resMap);
  152. const inMapConsumer = inSourceMap ? new source_map_1.SourceMapConsumer(inSourceMap) : null;
  153. const mergedMapGenerator = new source_map_1.SourceMapGenerator();
  154. let inMapFirstItem = null;
  155. if (inMapConsumer) {
  156. inMapConsumer.eachMapping(m => {
  157. if (inMapFirstItem) {
  158. return;
  159. }
  160. inMapFirstItem = m;
  161. });
  162. }
  163. resMapConsumer.eachMapping(res => {
  164. if (res.originalLine == null) {
  165. return;
  166. }
  167. const map = codeMaps.get(res.name);
  168. if (!map) {
  169. return;
  170. }
  171. let inMapOrigin = null;
  172. if (inMapConsumer) {
  173. inMapOrigin = inMapConsumer.originalPositionFor({
  174. line: res.originalLine,
  175. column: res.originalColumn - 1
  176. });
  177. if (inMapOrigin.source == null) {
  178. inMapOrigin = null;
  179. return;
  180. }
  181. }
  182. const mapConsumer = new source_map_1.SourceMapConsumer(map);
  183. mapConsumer.eachMapping(m => {
  184. mergedMapGenerator.addMapping({
  185. original: {
  186. line: inMapFirstItem
  187. ? inMapFirstItem.originalLine + res.originalLine - 2
  188. : res.originalLine,
  189. column: inMapFirstItem
  190. ? inMapFirstItem.originalColumn + res.originalColumn
  191. : res.originalColumn
  192. },
  193. generated: {
  194. line: inMapFirstItem
  195. ? inMapFirstItem.generatedLine + res.originalLine - 2
  196. : res.originalLine,
  197. // map column with message format compilation code map
  198. column: inMapFirstItem
  199. ? inMapFirstItem.generatedColumn +
  200. res.originalColumn +
  201. m.generatedColumn
  202. : res.originalColumn + m.generatedColumn
  203. },
  204. source: inMapOrigin ? inMapOrigin.source : res.source,
  205. name: m.name // message format compilation code
  206. });
  207. });
  208. });
  209. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  210. const generator = mergedMapGenerator;
  211. // const targetConsumer = inMapConsumer || resMapConsumer
  212. const targetConsumer = inMapConsumer || resMapConsumer;
  213. targetConsumer.sources.forEach((sourceFile) => {
  214. generator._sources.add(sourceFile);
  215. const sourceContent = targetConsumer.sourceContentFor(sourceFile);
  216. if (sourceContent != null) {
  217. mergedMapGenerator.setSourceContent(sourceFile, sourceContent);
  218. }
  219. });
  220. generator._sourceRoot = inSourceMap
  221. ? inSourceMap.sourceRoot
  222. : resMap.sourceRoot;
  223. generator._file = inSourceMap ? inSourceMap.file : resMap.file;
  224. return generator.toJSON();
  225. }
  226. exports.mapLinesColumns = mapLinesColumns;