BVB Source Codes

prettier Show index.js Source code

Return Download prettier: download index.js Source code - Download prettier Source code - Type:.js
  1. "use strict";
  2.  
  3. const comments = require("./src/comments");
  4. const version = require("./package.json").version;
  5. const printAstToDoc = require("./src/printer").printAstToDoc;
  6. const util = require("./src/util");
  7. const printDocToString = require("./src/doc-printer").printDocToString;
  8. const normalizeOptions = require("./src/options").normalize;
  9. const parser = require("./parser");
  10. const printDocToDebug = require("./src/doc-debug").printDocToDebug;
  11.  
  12. function guessLineEnding(text) {
  13.   const index = text.indexOf("\n");
  14.   if (index >= 0 && text.charAt(index - 1) === "\r") {
  15.     return "\r\n";
  16.   }
  17.   return "\n";
  18. }
  19.  
  20. function attachComments(text, ast, opts) {
  21.   const astComments = ast.comments;
  22.   if (astComments) {
  23.     delete ast.comments;
  24.     comments.attach(astComments, ast, text, opts);
  25.   }
  26.   ast.tokens = [];
  27.   opts.originalText = text.trimRight();
  28.   return astComments;
  29. }
  30.  
  31. function ensureAllCommentsPrinted(astComments) {
  32.   if (!astComments) {
  33.     return;
  34.   }
  35.  
  36.   for (let i = 0; i < astComments.length; ++i) {
  37.     if (astComments[i].value.trim() === "prettier-ignore") {
  38.       // If there's a prettier-ignore, we're not printing that sub-tree so we
  39.       // don't know if the comments was printed or not.
  40.       return;
  41.     }
  42.   }
  43.  
  44.   astComments.forEach(comment => {
  45.     if (!comment.printed) {
  46.       throw new Error(
  47.         'Comment "' +
  48.           comment.value.trim() +
  49.           '" was not printed. Please report this error!'
  50.       );
  51.     }
  52.     delete comment.printed;
  53.   });
  54. }
  55.  
  56. function formatWithCursor(text, opts, addAlignmentSize) {
  57.   addAlignmentSize = addAlignmentSize || 0;
  58.  
  59.   const ast = parser.parse(text, opts);
  60.  
  61.   const formattedRangeOnly = formatRange(text, opts, ast);
  62.   if (formattedRangeOnly) {
  63.     return { formatted: formattedRangeOnly };
  64.   }
  65.  
  66.   let cursorOffset;
  67.   if (opts.cursorOffset >= 0) {
  68.     const cursorNodeAndParents = findNodeAtOffset(ast, opts.cursorOffset);
  69.     const cursorNode = cursorNodeAndParents.node;
  70.     if (cursorNode) {
  71.       cursorOffset = opts.cursorOffset - util.locStart(cursorNode);
  72.       opts.cursorNode = cursorNode;
  73.     }
  74.   }
  75.  
  76.   const astComments = attachComments(text, ast, opts);
  77.   const doc = printAstToDoc(ast, opts, addAlignmentSize);
  78.   opts.newLine = guessLineEnding(text);
  79.   const toStringResult = printDocToString(doc, opts);
  80.   const str = toStringResult.formatted;
  81.   const cursorOffsetResult = toStringResult.cursor;
  82.   ensureAllCommentsPrinted(astComments);
  83.   // Remove extra leading indentation as well as the added indentation after last newline
  84.   if (addAlignmentSize > 0) {
  85.     return { formatted: str.trim() + opts.newLine };
  86.   }
  87.  
  88.   if (cursorOffset !== undefined) {
  89.     return {
  90.       formatted: str,
  91.       cursorOffset: cursorOffsetResult + cursorOffset
  92.     };
  93.   }
  94.  
  95.   return { formatted: str };
  96. }
  97.  
  98. function format(text, opts, addAlignmentSize) {
  99.   return formatWithCursor(text, opts, addAlignmentSize).formatted;
  100. }
  101.  
  102. function findSiblingAncestors(startNodeAndParents, endNodeAndParents) {
  103.   let resultStartNode = startNodeAndParents.node;
  104.   let resultEndNode = endNodeAndParents.node;
  105.  
  106.   for (const endParent of endNodeAndParents.parentNodes) {
  107.     if (util.locStart(endParent) >= util.locStart(startNodeAndParents.node)) {
  108.       resultEndNode = endParent;
  109.     } else {
  110.       break;
  111.     }
  112.   }
  113.  
  114.   for (const startParent of startNodeAndParents.parentNodes) {
  115.     if (util.locEnd(startParent) <= util.locEnd(endNodeAndParents.node)) {
  116.       resultStartNode = startParent;
  117.     } else {
  118.       break;
  119.     }
  120.   }
  121.  
  122.   return {
  123.     startNode: resultStartNode,
  124.     endNode: resultEndNode
  125.   };
  126. }
  127.  
  128. function findNodeAtOffset(node, offset, parentNodes) {
  129.   parentNodes = parentNodes || [];
  130.   const start = util.locStart(node);
  131.   const end = util.locEnd(node);
  132.   if (start <= offset && offset <= end) {
  133.     for (const childNode of comments.getSortedChildNodes(node)) {
  134.       const childResult = findNodeAtOffset(
  135.         childNode,
  136.         offset,
  137.         [node].concat(parentNodes)
  138.       );
  139.       if (childResult) {
  140.         return childResult;
  141.       }
  142.     }
  143.  
  144.     if (isSourceElement(node)) {
  145.       return {
  146.         node: node,
  147.         parentNodes: parentNodes
  148.       };
  149.     }
  150.   }
  151. }
  152.  
  153. // See https://www.ecma-international.org/ecma-262/5.1/#sec-A.5
  154. function isSourceElement(node) {
  155.   if (node == null) {
  156.     return false;
  157.   }
  158.   switch (node.type) {
  159.     case "FunctionDeclaration":
  160.     case "BlockStatement":
  161.     case "BreakStatement":
  162.     case "ContinueStatement":
  163.     case "DebuggerStatement":
  164.     case "DoWhileStatement":
  165.     case "EmptyStatement":
  166.     case "ExpressionStatement":
  167.     case "ForInStatement":
  168.     case "ForStatement":
  169.     case "IfStatement":
  170.     case "LabeledStatement":
  171.     case "ReturnStatement":
  172.     case "SwitchStatement":
  173.     case "ThrowStatement":
  174.     case "TryStatement":
  175.     case "VariableDeclaration":
  176.     case "WhileStatement":
  177.     case "WithStatement":
  178.       return true;
  179.   }
  180.   return false;
  181. }
  182.  
  183. function calculateRange(text, opts, ast) {
  184.   // Contract the range so that it has non-whitespace characters at its endpoints.
  185.   // This ensures we can format a range that doesn't end on a node.
  186.   const rangeStringOrig = text.slice(opts.rangeStart, opts.rangeEnd);
  187.   const startNonWhitespace = Math.max(
  188.     opts.rangeStart + rangeStringOrig.search(/\S/),
  189.     opts.rangeStart
  190.   );
  191.   let endNonWhitespace;
  192.   for (
  193.     endNonWhitespace = opts.rangeEnd;
  194.     endNonWhitespace > opts.rangeStart;
  195.     --endNonWhitespace
  196.   ) {
  197.     if (text[endNonWhitespace - 1].match(/\S/)) {
  198.       break;
  199.     }
  200.   }
  201.  
  202.   const startNodeAndParents = findNodeAtOffset(ast, startNonWhitespace);
  203.   const endNodeAndParents = findNodeAtOffset(ast, endNonWhitespace);
  204.   const siblingAncestors = findSiblingAncestors(
  205.     startNodeAndParents,
  206.     endNodeAndParents
  207.   );
  208.   const startNode = siblingAncestors.startNode;
  209.   const endNode = siblingAncestors.endNode;
  210.   const rangeStart = Math.min(util.locStart(startNode), util.locStart(endNode));
  211.   const rangeEnd = Math.max(util.locEnd(startNode), util.locEnd(endNode));
  212.  
  213.   return {
  214.     rangeStart: rangeStart,
  215.     rangeEnd: rangeEnd
  216.   };
  217. }
  218.  
  219. function formatRange(text, opts, ast) {
  220.   if (0 < opts.rangeStart || opts.rangeEnd < text.length) {
  221.     const range = calculateRange(text, opts, ast);
  222.     const rangeStart = range.rangeStart;
  223.     const rangeEnd = range.rangeEnd;
  224.     const rangeString = text.slice(rangeStart, rangeEnd);
  225.  
  226.     // Try to extend the range backwards to the beginning of the line.
  227.     // This is so we can detect indentation correctly and restore it.
  228.     // Use `Math.min` since `lastIndexOf` returns 0 when `rangeStart` is 0
  229.     const rangeStart2 = Math.min(
  230.       rangeStart,
  231.       text.lastIndexOf("\n", rangeStart) + 1
  232.     );
  233.     const indentString = text.slice(rangeStart2, rangeStart);
  234.  
  235.     const alignmentSize = util.getAlignmentSize(indentString, opts.tabWidth);
  236.  
  237.     const rangeFormatted = format(
  238.       rangeString,
  239.       Object.assign({}, opts, {
  240.         rangeStart: 0,
  241.         rangeEnd: Infinity,
  242.         printWidth: opts.printWidth - alignmentSize
  243.       }),
  244.       alignmentSize
  245.     );
  246.  
  247.     // Since the range contracts to avoid trailing whitespace,
  248.     // we need to remove the newline that was inserted by the `format` call.
  249.     const rangeTrimmed = rangeFormatted.trimRight();
  250.  
  251.     return text.slice(0, rangeStart) + rangeTrimmed + text.slice(rangeEnd);
  252.   }
  253. }
  254.  
  255. module.exports = {
  256.   formatWithCursor: function(text, opts) {
  257.     return formatWithCursor(text, normalizeOptions(opts));
  258.   },
  259.   format: function(text, opts) {
  260.     return format(text, normalizeOptions(opts));
  261.   },
  262.   check: function(text, opts) {
  263.     try {
  264.       const formatted = format(text, normalizeOptions(opts));
  265.       return formatted === text;
  266.     } catch (e) {
  267.       return false;
  268.     }
  269.   },
  270.   version: version,
  271.   __debug: {
  272.     parse: function(text, opts) {
  273.       return parser.parse(text, opts);
  274.     },
  275.     formatAST: function(ast, opts) {
  276.       opts = normalizeOptions(opts);
  277.       const doc = printAstToDoc(ast, opts);
  278.       const str = printDocToString(doc, opts);
  279.       return str;
  280.     },
  281.     // Doesn't handle shebang for now
  282.     formatDoc: function(doc, opts) {
  283.       opts = normalizeOptions(opts);
  284.       const debug = printDocToDebug(doc);
  285.       const str = format(debug, opts);
  286.       return str;
  287.     },
  288.     printToDoc: function(text, opts) {
  289.       opts = normalizeOptions(opts);
  290.       const ast = parser.parse(text, opts);
  291.       attachComments(text, ast, opts);
  292.       const doc = printAstToDoc(ast, opts);
  293.       return doc;
  294.     },
  295.     printDocToString: function(doc, opts) {
  296.       opts = normalizeOptions(opts);
  297.       const str = printDocToString(doc, opts);
  298.       return str;
  299.     }
  300.   }
  301. };
  302.  
downloadindex.js Source code - Download prettier Source code
Related Source Codes/Software:
storybook - 2017-06-07
ionicons - The premium icon font for Ionic ... 2017-06-07
AsyncDisplayKit - Smooth asynchronous user interfaces for iOS apps. ... 2017-06-07
lottie-android - Render After Effects animations natively on Androi... 2017-06-07
parse-server - Parse-compatible API server module for Node/Expres... 2017-06-07
inferno - An extremely fast, React-like JavaScript library f... 2017-06-08
guetzli - Perceptual JPEG encoder 2017-06-08
cs-video-courses - List of Computer Science courses with video lectur... 2017-06-08
interviews - Everything you need to know to get the job. 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top