From 646aab0a02b0e1b3966c392551d45a2791536e27 Mon Sep 17 00:00:00 2001 From: johnsoncodehk Date: Wed, 22 Feb 2023 19:24:18 +0800 Subject: [PATCH] feat: findDocumentSymbols2 --- src/htmlLanguageService.ts | 8 +++-- src/htmlLanguageTypes.ts | 4 +-- src/services/htmlSymbolsProvider.ts | 50 +++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/htmlLanguageService.ts b/src/htmlLanguageService.ts index 4c79fef..9ee5876 100644 --- a/src/htmlLanguageService.ts +++ b/src/htmlLanguageService.ts @@ -10,14 +10,14 @@ import { HTMLHover } from './services/htmlHover'; import { format } from './services/htmlFormatter'; import { findDocumentLinks } from './services/htmlLinks'; import { findDocumentHighlights } from './services/htmlHighlighting'; -import { findDocumentSymbols } from './services/htmlSymbolsProvider'; +import { findDocumentSymbols, findDocumentSymbols2 } from './services/htmlSymbolsProvider'; import { doRename } from './services/htmlRename'; import { findMatchingTagPosition } from './services/htmlMatchingTagPosition'; import { findLinkedEditingRanges } from './services/htmlLinkedEditing'; import { - Scanner, HTMLDocument, CompletionConfiguration, ICompletionParticipant, HTMLFormatConfiguration, DocumentContext, + Scanner, HTMLDocument, CompletionConfiguration, ICompletionParticipant, HTMLFormatConfiguration, DocumentContext, DocumentSymbol, IHTMLDataProvider, HTMLDataV1, LanguageServiceOptions, TextDocument, SelectionRange, WorkspaceEdit, - Position, CompletionList, Hover, Range, SymbolInformation, TextEdit, DocumentHighlight, DocumentLink, FoldingRange, HoverSettings + Position, CompletionList, Hover, Range, SymbolInformation, TextEdit, DocumentHighlight, DocumentLink, FoldingRange, HoverSettings, } from './htmlLanguageTypes'; import { HTMLFolding } from './services/htmlFolding'; import { HTMLSelectionRange } from './services/htmlSelectionRange'; @@ -39,6 +39,7 @@ export interface LanguageService { format(document: TextDocument, range: Range | undefined, options: HTMLFormatConfiguration): TextEdit[]; findDocumentLinks(document: TextDocument, documentContext: DocumentContext): DocumentLink[]; findDocumentSymbols(document: TextDocument, htmlDocument: HTMLDocument): SymbolInformation[]; + findDocumentSymbols2(document: TextDocument, htmlDocument: HTMLDocument): DocumentSymbol[]; doQuoteComplete(document: TextDocument, position: Position, htmlDocument: HTMLDocument, options?: CompletionConfiguration): string | null; doTagComplete(document: TextDocument, position: Position, htmlDocument: HTMLDocument): string | null; getFoldingRanges(document: TextDocument, context?: { rangeLimit?: number }): FoldingRange[]; @@ -73,6 +74,7 @@ export function getLanguageService(options: LanguageServiceOptions = defaultLang findDocumentHighlights, findDocumentLinks, findDocumentSymbols, + findDocumentSymbols2, getFoldingRanges: htmlFolding.getFoldingRanges.bind(htmlFolding), getSelectionRanges: htmlSelectionRange.getSelectionRanges.bind(htmlSelectionRange), doQuoteComplete: htmlCompletion.doQuoteComplete.bind(htmlCompletion), diff --git a/src/htmlLanguageTypes.ts b/src/htmlLanguageTypes.ts index cbb29a0..a1a6d1b 100644 --- a/src/htmlLanguageTypes.ts +++ b/src/htmlLanguageTypes.ts @@ -8,7 +8,7 @@ import { MarkupContent, MarkupKind, MarkedString, DocumentUri, SelectionRange, WorkspaceEdit, CompletionList, CompletionItemKind, CompletionItem, CompletionItemTag, InsertTextMode, Command, - SymbolInformation, SymbolKind, + SymbolInformation, DocumentSymbol, SymbolKind, Hover, TextEdit, InsertReplaceEdit, InsertTextFormat, DocumentHighlight, DocumentHighlightKind, DocumentLink, FoldingRange, FoldingRangeKind, SignatureHelp, Definition, Diagnostic, FormattingOptions, Color, ColorInformation, ColorPresentation @@ -22,7 +22,7 @@ export { MarkupContent, MarkupKind, MarkedString, DocumentUri, SelectionRange, WorkspaceEdit, CompletionList, CompletionItemKind, CompletionItem, CompletionItemTag, InsertTextMode, Command, - SymbolInformation, SymbolKind, + SymbolInformation, DocumentSymbol, SymbolKind, Hover, TextEdit, InsertReplaceEdit, InsertTextFormat, DocumentHighlight, DocumentHighlightKind, DocumentLink, FoldingRange, FoldingRangeKind, SignatureHelp, Definition, Diagnostic, FormattingOptions, Color, ColorInformation, ColorPresentation diff --git a/src/services/htmlSymbolsProvider.ts b/src/services/htmlSymbolsProvider.ts index f162862..6143c91 100644 --- a/src/services/htmlSymbolsProvider.ts +++ b/src/services/htmlSymbolsProvider.ts @@ -3,38 +3,62 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Location, Range, SymbolInformation, SymbolKind, TextDocument} from '../htmlLanguageTypes'; +import { DocumentSymbol, Range, SymbolInformation, SymbolKind, TextDocument } from '../htmlLanguageTypes'; import { HTMLDocument, Node } from '../parser/htmlParser'; export function findDocumentSymbols(document: TextDocument, htmlDocument: HTMLDocument): SymbolInformation[] { - const symbols = []; + const symbols: SymbolInformation[] = []; + const symbols2 = findDocumentSymbols2(document, htmlDocument); + + for (const symbol of symbols2) { + walk(symbol, undefined); + } + + return symbols; + + function walk(node: DocumentSymbol, parent: DocumentSymbol | undefined) { + const symbol = SymbolInformation.create(node.name, node.kind, node.range, document.uri, parent?.name); + symbol.containerName ??= ''; + symbols.push(symbol); + + if (node.children) { + for (const child of node.children) { + walk(child, node); + } + } + } +} + +export function findDocumentSymbols2(document: TextDocument, htmlDocument: HTMLDocument): DocumentSymbol[] { + const symbols: DocumentSymbol[] = []; htmlDocument.roots.forEach(node => { - provideFileSymbolsInternal(document, node, '', symbols); + provideFileSymbolsInternal(document, node, symbols); }); return symbols; } -function provideFileSymbolsInternal(document: TextDocument, node: Node, container: string, symbols: SymbolInformation[]): void { +function provideFileSymbolsInternal(document: TextDocument, node: Node, symbols: DocumentSymbol[]): void { const name = nodeToName(node); - const location = Location.create(document.uri, Range.create(document.positionAt(node.start), document.positionAt(node.end))); - const symbol = { - name: name, - location: location, - containerName: container, - kind: SymbolKind.Field - }; + const range = Range.create(document.positionAt(node.start), document.positionAt(node.end)); + const symbol = DocumentSymbol.create( + name, + undefined, + SymbolKind.Field, + range, + range, + ); symbols.push(symbol); node.children.forEach(child => { - provideFileSymbolsInternal(document, child, name, symbols); + symbol.children ??= []; + provideFileSymbolsInternal(document, child, symbol.children); }); } - function nodeToName(node: Node): string { let name = node.tag;