2 if (typeof module === "object" && typeof module.exports === "object") {
3 var v = factory(require, exports);
4 if (v !== undefined) module.exports = v;
6 else if (typeof define === "function" && define.amd) {
7 define(["require", "exports", "./scanner"], factory);
9 })(function (require, exports) {
10 /*---------------------------------------------------------------------------------------------
11 * Copyright (c) Microsoft Corporation. All rights reserved.
12 * Licensed under the MIT License. See License.txt in the project root for license information.
13 *--------------------------------------------------------------------------------------------*/
15 Object.defineProperty(exports, "__esModule", { value: true });
16 exports.isEOL = exports.format = void 0;
17 var scanner_1 = require("./scanner");
18 function format(documentText, range, options) {
19 var initialIndentLevel;
25 rangeStart = range.offset;
26 rangeEnd = rangeStart + range.length;
27 formatTextStart = rangeStart;
28 while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
31 var endOffset = rangeEnd;
32 while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
35 formatText = documentText.substring(formatTextStart, endOffset);
36 initialIndentLevel = computeIndentLevel(formatText, options);
39 formatText = documentText;
40 initialIndentLevel = 0;
43 rangeEnd = documentText.length;
45 var eol = getEOL(options, documentText);
46 var lineBreak = false;
49 if (options.insertSpaces) {
50 indentValue = repeat(' ', options.tabSize || 4);
55 var scanner = scanner_1.createScanner(formatText, false);
57 function newLineAndIndent() {
58 return eol + repeat(indentValue, initialIndentLevel + indentLevel);
61 var token = scanner.scan();
63 while (token === 15 /* Trivia */ || token === 14 /* LineBreakTrivia */) {
64 lineBreak = lineBreak || (token === 14 /* LineBreakTrivia */);
65 token = scanner.scan();
67 hasError = token === 16 /* Unknown */ || scanner.getTokenError() !== 0 /* None */;
70 var editOperations = [];
71 function addEdit(text, startOffset, endOffset) {
72 if (!hasError && (!range || (startOffset < rangeEnd && endOffset > rangeStart)) && documentText.substring(startOffset, endOffset) !== text) {
73 editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
76 var firstToken = scanNext();
77 if (firstToken !== 17 /* EOF */) {
78 var firstTokenStart = scanner.getTokenOffset() + formatTextStart;
79 var initialIndent = repeat(indentValue, initialIndentLevel);
80 addEdit(initialIndent, formatTextStart, firstTokenStart);
82 while (firstToken !== 17 /* EOF */) {
83 var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
84 var secondToken = scanNext();
85 var replaceContent = '';
86 var needsLineBreak = false;
87 while (!lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) {
88 // comments on the same line: keep them on the same line, but ignore them otherwise
89 var commentTokenStart = scanner.getTokenOffset() + formatTextStart;
90 addEdit(' ', firstTokenEnd, commentTokenStart);
91 firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
92 needsLineBreak = secondToken === 12 /* LineCommentTrivia */;
93 replaceContent = needsLineBreak ? newLineAndIndent() : '';
94 secondToken = scanNext();
96 if (secondToken === 2 /* CloseBraceToken */) {
97 if (firstToken !== 1 /* OpenBraceToken */) {
99 replaceContent = newLineAndIndent();
102 else if (secondToken === 4 /* CloseBracketToken */) {
103 if (firstToken !== 3 /* OpenBracketToken */) {
105 replaceContent = newLineAndIndent();
109 switch (firstToken) {
110 case 3 /* OpenBracketToken */:
111 case 1 /* OpenBraceToken */:
113 replaceContent = newLineAndIndent();
115 case 5 /* CommaToken */:
116 case 12 /* LineCommentTrivia */:
117 replaceContent = newLineAndIndent();
119 case 13 /* BlockCommentTrivia */:
121 replaceContent = newLineAndIndent();
123 else if (!needsLineBreak) {
124 // symbol following comment on the same line: keep on same line, separate with ' '
125 replaceContent = ' ';
128 case 6 /* ColonToken */:
129 if (!needsLineBreak) {
130 replaceContent = ' ';
133 case 10 /* StringLiteral */:
134 if (secondToken === 6 /* ColonToken */) {
135 if (!needsLineBreak) {
141 case 7 /* NullKeyword */:
142 case 8 /* TrueKeyword */:
143 case 9 /* FalseKeyword */:
144 case 11 /* NumericLiteral */:
145 case 2 /* CloseBraceToken */:
146 case 4 /* CloseBracketToken */:
147 if (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */) {
148 if (!needsLineBreak) {
149 replaceContent = ' ';
152 else if (secondToken !== 5 /* CommaToken */ && secondToken !== 17 /* EOF */) {
156 case 16 /* Unknown */:
160 if (lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) {
161 replaceContent = newLineAndIndent();
164 if (secondToken === 17 /* EOF */) {
165 replaceContent = options.insertFinalNewline ? eol : '';
167 var secondTokenStart = scanner.getTokenOffset() + formatTextStart;
168 addEdit(replaceContent, firstTokenEnd, secondTokenStart);
169 firstToken = secondToken;
171 return editOperations;
173 exports.format = format;
174 function repeat(s, count) {
176 for (var i = 0; i < count; i++) {
181 function computeIndentLevel(content, options) {
184 var tabSize = options.tabSize || 4;
185 while (i < content.length) {
186 var ch = content.charAt(i);
190 else if (ch === '\t') {
198 return Math.floor(nChars / tabSize);
200 function getEOL(options, text) {
201 for (var i = 0; i < text.length; i++) {
202 var ch = text.charAt(i);
204 if (i + 1 < text.length && text.charAt(i + 1) === '\n') {
209 else if (ch === '\n') {
213 return (options && options.eol) || '\n';
215 function isEOL(text, offset) {
216 return '\r\n'.indexOf(text.charAt(offset)) !== -1;
218 exports.isEOL = isEOL;