jsonFolding.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. (function (factory) {
  6. if (typeof module === "object" && typeof module.exports === "object") {
  7. var v = factory(require, exports);
  8. if (v !== undefined) module.exports = v;
  9. }
  10. else if (typeof define === "function" && define.amd) {
  11. define(["require", "exports", "jsonc-parser", "../jsonLanguageTypes"], factory);
  12. }
  13. })(function (require, exports) {
  14. "use strict";
  15. Object.defineProperty(exports, "__esModule", { value: true });
  16. exports.getFoldingRanges = void 0;
  17. var jsonc_parser_1 = require("jsonc-parser");
  18. var jsonLanguageTypes_1 = require("../jsonLanguageTypes");
  19. function getFoldingRanges(document, context) {
  20. var ranges = [];
  21. var nestingLevels = [];
  22. var stack = [];
  23. var prevStart = -1;
  24. var scanner = jsonc_parser_1.createScanner(document.getText(), false);
  25. var token = scanner.scan();
  26. function addRange(range) {
  27. ranges.push(range);
  28. nestingLevels.push(stack.length);
  29. }
  30. while (token !== 17 /* EOF */) {
  31. switch (token) {
  32. case 1 /* OpenBraceToken */:
  33. case 3 /* OpenBracketToken */: {
  34. var startLine = document.positionAt(scanner.getTokenOffset()).line;
  35. var range = { startLine: startLine, endLine: startLine, kind: token === 1 /* OpenBraceToken */ ? 'object' : 'array' };
  36. stack.push(range);
  37. break;
  38. }
  39. case 2 /* CloseBraceToken */:
  40. case 4 /* CloseBracketToken */: {
  41. var kind = token === 2 /* CloseBraceToken */ ? 'object' : 'array';
  42. if (stack.length > 0 && stack[stack.length - 1].kind === kind) {
  43. var range = stack.pop();
  44. var line = document.positionAt(scanner.getTokenOffset()).line;
  45. if (range && line > range.startLine + 1 && prevStart !== range.startLine) {
  46. range.endLine = line - 1;
  47. addRange(range);
  48. prevStart = range.startLine;
  49. }
  50. }
  51. break;
  52. }
  53. case 13 /* BlockCommentTrivia */: {
  54. var startLine = document.positionAt(scanner.getTokenOffset()).line;
  55. var endLine = document.positionAt(scanner.getTokenOffset() + scanner.getTokenLength()).line;
  56. if (scanner.getTokenError() === 1 /* UnexpectedEndOfComment */ && startLine + 1 < document.lineCount) {
  57. scanner.setPosition(document.offsetAt(jsonLanguageTypes_1.Position.create(startLine + 1, 0)));
  58. }
  59. else {
  60. if (startLine < endLine) {
  61. addRange({ startLine: startLine, endLine: endLine, kind: jsonLanguageTypes_1.FoldingRangeKind.Comment });
  62. prevStart = startLine;
  63. }
  64. }
  65. break;
  66. }
  67. case 12 /* LineCommentTrivia */: {
  68. var text = document.getText().substr(scanner.getTokenOffset(), scanner.getTokenLength());
  69. var m = text.match(/^\/\/\s*#(region\b)|(endregion\b)/);
  70. if (m) {
  71. var line = document.positionAt(scanner.getTokenOffset()).line;
  72. if (m[1]) { // start pattern match
  73. var range = { startLine: line, endLine: line, kind: jsonLanguageTypes_1.FoldingRangeKind.Region };
  74. stack.push(range);
  75. }
  76. else {
  77. var i = stack.length - 1;
  78. while (i >= 0 && stack[i].kind !== jsonLanguageTypes_1.FoldingRangeKind.Region) {
  79. i--;
  80. }
  81. if (i >= 0) {
  82. var range = stack[i];
  83. stack.length = i;
  84. if (line > range.startLine && prevStart !== range.startLine) {
  85. range.endLine = line;
  86. addRange(range);
  87. prevStart = range.startLine;
  88. }
  89. }
  90. }
  91. }
  92. break;
  93. }
  94. }
  95. token = scanner.scan();
  96. }
  97. var rangeLimit = context && context.rangeLimit;
  98. if (typeof rangeLimit !== 'number' || ranges.length <= rangeLimit) {
  99. return ranges;
  100. }
  101. if (context && context.onRangeLimitExceeded) {
  102. context.onRangeLimitExceeded(document.uri);
  103. }
  104. var counts = [];
  105. for (var _i = 0, nestingLevels_1 = nestingLevels; _i < nestingLevels_1.length; _i++) {
  106. var level = nestingLevels_1[_i];
  107. if (level < 30) {
  108. counts[level] = (counts[level] || 0) + 1;
  109. }
  110. }
  111. var entries = 0;
  112. var maxLevel = 0;
  113. for (var i = 0; i < counts.length; i++) {
  114. var n = counts[i];
  115. if (n) {
  116. if (n + entries > rangeLimit) {
  117. maxLevel = i;
  118. break;
  119. }
  120. entries += n;
  121. }
  122. }
  123. var result = [];
  124. for (var i = 0; i < ranges.length; i++) {
  125. var level = nestingLevels[i];
  126. if (typeof level === 'number') {
  127. if (level < maxLevel || (level === maxLevel && entries++ < rangeLimit)) {
  128. result.push(ranges[i]);
  129. }
  130. }
  131. }
  132. return result;
  133. }
  134. exports.getFoldingRanges = getFoldingRanges;
  135. });