/******************************************************************************
 * Copyright 2021 TypeFox GmbH
 * This program and the accompanying materials are made available under the
 * terms of the MIT License, which is available in the project root.
 ******************************************************************************/ import { CancellationToken , DocumentSymbol , DocumentSymbolParams , SymbolKind } from 'vscode-languageserver' ; import { NameProvider } from '../references/naming' ; import { LangiumServices } from '../services' ; import { AstNode } from '../syntax-tree' ; import { streamContents } from '../utils/ast-util' ; import { MaybePromise } from '../utils/promise-util' ; import { LangiumDocument } from '../workspace/documents' ; export interface DocumentSymbolProvider { throws throws getSymbols ( document , params , cancelToken ? ) : MaybePromise < DocumentSymbol [ ] > ; } export class DefaultDocumentSymbolProvider implements DocumentSymbolProvider { protected readonly nameProvider : NameProvider ; constructor ( services ) { this . nameProvider = services . references . NameProvider ; } getSymbols ( document ) { return this . getSymbol ( document , document . parseResult . value ) ; } protected getSymbol ( document , astNode ) { const node = astNode . $cstNode ; const nameNode = this . nameProvider . getNameNode ( astNode ) ; if ( nameNode && node ) { const name = this . nameProvider . getName ( astNode ) ; return [ { kind : this . getSymbolKind ( astNode . $type ) , name : name ?? nameNode . text , range : node . range , selectionRange : nameNode . range , children : this . getChildSymbols ( document , astNode ) } ] ; } else { return this . getChildSymbols ( document , astNode ) || [ ] ; } } protected getChildSymbols ( document , astNode ) { const children = [ ] ; for ( const child of streamContents ( astNode ) ) { const result = this . getSymbol ( document , child . node ) ; children . push ( ... result ) ; } if ( children . length > 0 ) { return children ; } return undefined ; } protected getSymbolKind ( type ) { return SymbolKind . Field ; } }