UNPKG

jsonc-parser

Version:
208 lines 9.03 kB
(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "./main"], factory); } })(function (require, exports) { /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var Json = require("./main"); function format(documentText, range, options) { var initialIndentLevel; var formatText; var formatTextStart; var rangeStart; var rangeEnd; if (range) { rangeStart = range.offset; rangeEnd = rangeStart + range.length; formatTextStart = rangeStart; while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) { formatTextStart--; } var endOffset = rangeEnd; while (endOffset < documentText.length && !isEOL(documentText, endOffset)) { endOffset++; } formatText = documentText.substring(formatTextStart, endOffset); initialIndentLevel = computeIndentLevel(formatText, 0, options); } else { formatText = documentText; initialIndentLevel = 0; formatTextStart = 0; rangeStart = 0; rangeEnd = documentText.length; } var eol = getEOL(options, documentText); var lineBreak = false; var indentLevel = 0; var indentValue; if (options.insertSpaces) { indentValue = repeat(' ', options.tabSize || 4); } else { indentValue = '\t'; } var scanner = Json.createScanner(formatText, false); var hasError = false; function newLineAndIndent() { return eol + repeat(indentValue, initialIndentLevel + indentLevel); } function scanNext() { var token = scanner.scan(); lineBreak = false; while (token === Json.SyntaxKind.Trivia || token === Json.SyntaxKind.LineBreakTrivia) { lineBreak = lineBreak || (token === Json.SyntaxKind.LineBreakTrivia); token = scanner.scan(); } hasError = token === Json.SyntaxKind.Unknown || scanner.getTokenError() !== Json.ScanError.None; return token; } var editOperations = []; function addEdit(text, startOffset, endOffset) { if (!hasError && startOffset < rangeEnd && endOffset > rangeStart && documentText.substring(startOffset, endOffset) !== text) { editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text }); } } var firstToken = scanNext(); if (firstToken !== Json.SyntaxKind.EOF) { var firstTokenStart = scanner.getTokenOffset() + formatTextStart; var initialIndent = repeat(indentValue, initialIndentLevel); addEdit(initialIndent, formatTextStart, firstTokenStart); } while (firstToken !== Json.SyntaxKind.EOF) { var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; var secondToken = scanNext(); var replaceContent = ''; while (!lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) { // comments on the same line: keep them on the same line, but ignore them otherwise var commentTokenStart = scanner.getTokenOffset() + formatTextStart; addEdit(' ', firstTokenEnd, commentTokenStart); firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; replaceContent = secondToken === Json.SyntaxKind.LineCommentTrivia ? newLineAndIndent() : ''; secondToken = scanNext(); } if (secondToken === Json.SyntaxKind.CloseBraceToken) { if (firstToken !== Json.SyntaxKind.OpenBraceToken) { indentLevel--; replaceContent = newLineAndIndent(); } } else if (secondToken === Json.SyntaxKind.CloseBracketToken) { if (firstToken !== Json.SyntaxKind.OpenBracketToken) { indentLevel--; replaceContent = newLineAndIndent(); } } else { switch (firstToken) { case Json.SyntaxKind.OpenBracketToken: case Json.SyntaxKind.OpenBraceToken: indentLevel++; replaceContent = newLineAndIndent(); break; case Json.SyntaxKind.CommaToken: case Json.SyntaxKind.LineCommentTrivia: replaceContent = newLineAndIndent(); break; case Json.SyntaxKind.BlockCommentTrivia: if (lineBreak) { replaceContent = newLineAndIndent(); } else { // symbol following comment on the same line: keep on same line, separate with ' ' replaceContent = ' '; } break; case Json.SyntaxKind.ColonToken: replaceContent = ' '; break; case Json.SyntaxKind.StringLiteral: if (secondToken === Json.SyntaxKind.ColonToken) { replaceContent = ''; break; } // fall through case Json.SyntaxKind.NullKeyword: case Json.SyntaxKind.TrueKeyword: case Json.SyntaxKind.FalseKeyword: case Json.SyntaxKind.NumericLiteral: case Json.SyntaxKind.CloseBraceToken: case Json.SyntaxKind.CloseBracketToken: if (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia) { replaceContent = ' '; } else if (secondToken !== Json.SyntaxKind.CommaToken && secondToken !== Json.SyntaxKind.EOF) { hasError = true; } break; case Json.SyntaxKind.Unknown: hasError = true; break; } if (lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) { replaceContent = newLineAndIndent(); } } var secondTokenStart = scanner.getTokenOffset() + formatTextStart; addEdit(replaceContent, firstTokenEnd, secondTokenStart); firstToken = secondToken; } return editOperations; } exports.format = format; function repeat(s, count) { var result = ''; for (var i = 0; i < count; i++) { result += s; } return result; } function computeIndentLevel(content, offset, options) { var i = 0; var nChars = 0; var tabSize = options.tabSize || 4; while (i < content.length) { var ch = content.charAt(i); if (ch === ' ') { nChars++; } else if (ch === '\t') { nChars += tabSize; } else { break; } i++; } return Math.floor(nChars / tabSize); } function getEOL(options, text) { for (var i = 0; i < text.length; i++) { var ch = text.charAt(i); if (ch === '\r') { if (i + 1 < text.length && text.charAt(i + 1) === '\n') { return '\r\n'; } return '\r'; } else if (ch === '\n') { return '\n'; } } return (options && options.eol) || '\n'; } function isEOL(text, offset) { return '\r\n'.indexOf(text.charAt(offset)) !== -1; } exports.isEOL = isEOL; }); //# sourceMappingURL=format.js.map