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 import { createScanner } from 'jsonc-parser';
6 import { FoldingRangeKind, Position } from '../jsonLanguageTypes';
7 export function getFoldingRanges(document, context) {
9 var nestingLevels = [];
12 var scanner = createScanner(document.getText(), false);
13 var token = scanner.scan();
14 function addRange(range) {
16 nestingLevels.push(stack.length);
18 while (token !== 17 /* EOF */) {
20 case 1 /* OpenBraceToken */:
21 case 3 /* OpenBracketToken */: {
22 var startLine = document.positionAt(scanner.getTokenOffset()).line;
23 var range = { startLine: startLine, endLine: startLine, kind: token === 1 /* OpenBraceToken */ ? 'object' : 'array' };
27 case 2 /* CloseBraceToken */:
28 case 4 /* CloseBracketToken */: {
29 var kind = token === 2 /* CloseBraceToken */ ? 'object' : 'array';
30 if (stack.length > 0 && stack[stack.length - 1].kind === kind) {
31 var range = stack.pop();
32 var line = document.positionAt(scanner.getTokenOffset()).line;
33 if (range && line > range.startLine + 1 && prevStart !== range.startLine) {
34 range.endLine = line - 1;
36 prevStart = range.startLine;
41 case 13 /* BlockCommentTrivia */: {
42 var startLine = document.positionAt(scanner.getTokenOffset()).line;
43 var endLine = document.positionAt(scanner.getTokenOffset() + scanner.getTokenLength()).line;
44 if (scanner.getTokenError() === 1 /* UnexpectedEndOfComment */ && startLine + 1 < document.lineCount) {
45 scanner.setPosition(document.offsetAt(Position.create(startLine + 1, 0)));
48 if (startLine < endLine) {
49 addRange({ startLine: startLine, endLine: endLine, kind: FoldingRangeKind.Comment });
50 prevStart = startLine;
55 case 12 /* LineCommentTrivia */: {
56 var text = document.getText().substr(scanner.getTokenOffset(), scanner.getTokenLength());
57 var m = text.match(/^\/\/\s*#(region\b)|(endregion\b)/);
59 var line = document.positionAt(scanner.getTokenOffset()).line;
60 if (m[1]) { // start pattern match
61 var range = { startLine: line, endLine: line, kind: FoldingRangeKind.Region };
65 var i = stack.length - 1;
66 while (i >= 0 && stack[i].kind !== FoldingRangeKind.Region) {
72 if (line > range.startLine && prevStart !== range.startLine) {
75 prevStart = range.startLine;
83 token = scanner.scan();
85 var rangeLimit = context && context.rangeLimit;
86 if (typeof rangeLimit !== 'number' || ranges.length <= rangeLimit) {
89 if (context && context.onRangeLimitExceeded) {
90 context.onRangeLimitExceeded(document.uri);
93 for (var _i = 0, nestingLevels_1 = nestingLevels; _i < nestingLevels_1.length; _i++) {
94 var level = nestingLevels_1[_i];
96 counts[level] = (counts[level] || 0) + 1;
101 for (var i = 0; i < counts.length; i++) {
104 if (n + entries > rangeLimit) {
112 for (var i = 0; i < ranges.length; i++) {
113 var level = nestingLevels[i];
114 if (typeof level === 'number') {
115 if (level < maxLevel || (level === maxLevel && entries++ < rangeLimit)) {
116 result.push(ranges[i]);