[html] embedded folding ranges computed too many times (fixes #47712)

This commit is contained in:
Martin Aeschlimann
2018-09-18 18:23:05 +02:00
parent 7540711d86
commit 486ac95f43
5 changed files with 31 additions and 19 deletions

View File

@@ -57,10 +57,9 @@ export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegio
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.getColorPresentations(embedded, cssStylesheets.get(embedded), color, range);
},
getFoldingRanges(document: TextDocument, range: Range): FoldingRange[] {
getFoldingRanges(document: TextDocument): FoldingRange[] {
let embedded = embeddedCSSDocuments.get(document);
let ranges = cssLanguageService.getFoldingRanges(embedded, {});
return ranges.filter(r => r.startLine >= range.start.line && r.endLine < range.end.line);
return cssLanguageService.getFoldingRanges(embedded, {});
},
onDocumentRemoved(document: TextDocument) {
embeddedCSSDocuments.onDocumentRemoved(document);

View File

@@ -5,26 +5,42 @@
'use strict';
import { TextDocument, CancellationToken, Position, Range } from 'vscode-languageserver';
import { FoldingRange } from 'vscode-languageserver-types';
import { LanguageModes } from './languageModes';
import { LanguageModes, LanguageMode } from './languageModes';
export function getFoldingRanges(languageModes: LanguageModes, document: TextDocument, maxRanges: number | undefined, cancellationToken: CancellationToken | null): FoldingRange[] {
let htmlMode = languageModes.getMode('html');
let range = Range.create(Position.create(0, 0), Position.create(document.lineCount, 0));
let ranges: FoldingRange[] = [];
let result: FoldingRange[] = [];
if (htmlMode && htmlMode.getFoldingRanges) {
ranges.push(...htmlMode.getFoldingRanges(document, range));
result.push(...htmlMode.getFoldingRanges(document));
}
// cache folding ranges per mode
let rangesPerMode: { [mode: string]: FoldingRange[] } = Object.create(null);
let getRangesForMode = (mode: LanguageMode) => {
if (mode.getFoldingRanges) {
let ranges = rangesPerMode[mode.getId()];
if (!Array.isArray(ranges)) {
ranges = mode.getFoldingRanges(document) || [];
rangesPerMode[mode.getId()] = ranges;
}
return ranges;
}
return [];
};
let modeRanges = languageModes.getModesInRange(document, range);
for (let modeRange of modeRanges) {
let mode = modeRange.mode;
if (mode && mode !== htmlMode && mode.getFoldingRanges && !modeRange.attributeValue) {
ranges.push(...mode.getFoldingRanges(document, modeRange));
if (mode && mode !== htmlMode && !modeRange.attributeValue) {
const ranges = getRangesForMode(mode);
result.push(...ranges.filter(r => r.startLine >= modeRange.start.line && r.endLine < modeRange.end.line));
}
}
if (maxRanges && ranges.length > maxRanges) {
ranges = limitRanges(ranges, maxRanges);
if (maxRanges && result.length > maxRanges) {
result = limitRanges(result, maxRanges);
}
return ranges;
return result;
}
function limitRanges(ranges: FoldingRange[], maxRanges: number) {

View File

@@ -58,9 +58,8 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace:
formatSettings = merge(formatParams, formatSettings);
return htmlLanguageService.format(document, range, formatSettings);
},
getFoldingRanges(document: TextDocument, range: Range): FoldingRange[] {
let ranges = htmlLanguageService.getFoldingRanges(document);
return ranges.filter(r => r.startLine >= range.start.line && r.endLine < range.end.line);
getFoldingRanges(document: TextDocument): FoldingRange[] {
return htmlLanguageService.getFoldingRanges(document);
},
doAutoClose(document: TextDocument, position: Position) {
let offset = document.offsetAt(position);

View File

@@ -283,17 +283,15 @@ export function getJavaScriptMode(documentRegions: LanguageModelCache<HTMLDocume
}
return [];
},
getFoldingRanges(document: TextDocument, range: Range): FoldingRange[] {
getFoldingRanges(document: TextDocument): FoldingRange[] {
updateCurrentTextDocument(document);
let spans = jsLanguageService.getOutliningSpans(FILE_NAME);
let rangeStartLine = range.start.line;
let rangeEndLine = range.end.line;
let ranges: FoldingRange[] = [];
for (let span of spans) {
let curr = convertRange(currentTextDocument, span.textSpan);
let startLine = curr.start.line;
let endLine = curr.end.line;
if (startLine < endLine && startLine >= rangeStartLine && endLine < rangeEndLine) {
if (startLine < endLine) {
let foldingRange: FoldingRange = { startLine, endLine };
let match = document.getText(curr).match(/^\s*\/(?:(\/\s*#(?:end)?region\b)|(\*|\/))/);
if (match) {

View File

@@ -46,7 +46,7 @@ export interface LanguageMode {
findDocumentColors?: (document: TextDocument) => ColorInformation[];
getColorPresentations?: (document: TextDocument, color: Color, range: Range) => ColorPresentation[];
doAutoClose?: (document: TextDocument, position: Position) => string | null;
getFoldingRanges?: (document: TextDocument, range: Range) => FoldingRange[];
getFoldingRanges?: (document: TextDocument) => FoldingRange[];
onDocumentRemoved(document: TextDocument): void;
dispose(): void;
}