UNPKG

typescript-language-server

Version:

Language Server Protocol (LSP) implementation for TypeScript using tsserver

85 lines 3.42 kB
/* * Copyright (C) 2017, 2018 TypeFox and others. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 */ import { toSymbolKind } from './protocol-translation.js'; import { ScriptElementKind } from './tsp-command-types.js'; import { Range } from './utils/typeConverters.js'; export function collectDocumentSymbols(parent, symbols) { return collectDocumentSymbolsInRange(parent, symbols, { start: Range.fromTextSpan(parent.spans[0]).start, end: Range.fromTextSpan(parent.spans[parent.spans.length - 1]).end }); } function collectDocumentSymbolsInRange(parent, symbols, range) { let shouldInclude = shouldIncludeEntry(parent); for (const span of parent.spans) { const spanRange = Range.fromTextSpan(span); if (!Range.intersection(range, spanRange)) { continue; } const children = []; if (parent.childItems) { for (const child of parent.childItems) { if (child.spans.some(childSpan => !!Range.intersection(spanRange, Range.fromTextSpan(childSpan)))) { const includedChild = collectDocumentSymbolsInRange(child, children, spanRange); shouldInclude = shouldInclude || includedChild; } } } let selectionRange = spanRange; if (parent.nameSpan) { const nameRange = Range.fromTextSpan(parent.nameSpan); // In the case of mergeable definitions, the nameSpan is only correct for the first definition. if (Range.intersection(spanRange, nameRange)) { selectionRange = nameRange; } } if (shouldInclude) { symbols.push({ name: parent.text, detail: '', kind: toSymbolKind(parent.kind), range: spanRange, selectionRange: selectionRange, children, }); } } return shouldInclude; } export function collectSymbolInformation(uri, current, symbols, containerName) { let shouldInclude = shouldIncludeEntry(current); const name = current.text; for (const span of current.spans) { const range = Range.fromTextSpan(span); const children = []; if (current.childItems) { for (const child of current.childItems) { if (child.spans.some(span => !!Range.intersection(range, Range.fromTextSpan(span)))) { const includedChild = collectSymbolInformation(uri, child, children, name); shouldInclude = shouldInclude || includedChild; } } } if (shouldInclude) { symbols.push({ name, kind: toSymbolKind(current.kind), location: { uri, range, }, containerName, }); symbols.push(...children); } } return shouldInclude; } export function shouldIncludeEntry(item) { if (item.kind === ScriptElementKind.alias) { return false; } return !!(item.text && item.text !== '<function>' && item.text !== '<class>'); } //# sourceMappingURL=document-symbol.js.map