Path: blob/main/src/vs/editor/common/model/bracketPairsTextModelPart/fixBrackets.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { ILanguageConfigurationService } from '../../languages/languageConfigurationRegistry.js';6import { AstNode, AstNodeKind } from './bracketPairsTree/ast.js';7import { LanguageAgnosticBracketTokens } from './bracketPairsTree/brackets.js';8import { Length, lengthAdd, lengthGetColumnCountIfZeroLineCount, lengthZero } from './bracketPairsTree/length.js';9import { parseDocument } from './bracketPairsTree/parser.js';10import { DenseKeyProvider } from './bracketPairsTree/smallImmutableSet.js';11import { ITokenizerSource, TextBufferTokenizer } from './bracketPairsTree/tokenizer.js';12import { IViewLineTokens } from '../../tokens/lineTokens.js';1314export function fixBracketsInLine(tokens: IViewLineTokens, languageConfigurationService: ILanguageConfigurationService): string {15const denseKeyProvider = new DenseKeyProvider<string>();16const bracketTokens = new LanguageAgnosticBracketTokens(denseKeyProvider, (languageId) =>17languageConfigurationService.getLanguageConfiguration(languageId)18);19const tokenizer = new TextBufferTokenizer(20new StaticTokenizerSource([tokens]),21bracketTokens22);23const node = parseDocument(tokenizer, [], undefined, true);2425let str = '';26const line = tokens.getLineContent();2728function processNode(node: AstNode, offset: Length) {29if (node.kind === AstNodeKind.Pair) {30processNode(node.openingBracket, offset);31offset = lengthAdd(offset, node.openingBracket.length);3233if (node.child) {34processNode(node.child, offset);35offset = lengthAdd(offset, node.child.length);36}37if (node.closingBracket) {38processNode(node.closingBracket, offset);39offset = lengthAdd(offset, node.closingBracket.length);40} else {41const singleLangBracketTokens = bracketTokens.getSingleLanguageBracketTokens(node.openingBracket.languageId);4243const closingTokenText = singleLangBracketTokens.findClosingTokenText(node.openingBracket.bracketIds);44str += closingTokenText;45}46} else if (node.kind === AstNodeKind.UnexpectedClosingBracket) {47// remove the bracket48} else if (node.kind === AstNodeKind.Text || node.kind === AstNodeKind.Bracket) {49str += line.substring(50lengthGetColumnCountIfZeroLineCount(offset),51lengthGetColumnCountIfZeroLineCount(lengthAdd(offset, node.length))52);53} else if (node.kind === AstNodeKind.List) {54for (const child of node.children) {55processNode(child, offset);56offset = lengthAdd(offset, child.length);57}58}59}6061processNode(node, lengthZero);6263return str;64}6566class StaticTokenizerSource implements ITokenizerSource {67constructor(private readonly lines: IViewLineTokens[]) { }6869getValue(): string {70return this.lines.map(l => l.getLineContent()).join('\n');71}72getLineCount(): number {73return this.lines.length;74}75getLineLength(lineNumber: number): number {76return this.lines[lineNumber - 1].getLineContent().length;77}7879tokenization = {80getLineTokens: (lineNumber: number): IViewLineTokens => {81return this.lines[lineNumber - 1];82}83};84}858687