UNPKG

yaml-language-server

Version:
233 lines 9.91 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Red Hat, Inc. All rights reserved. * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "vscode-languageserver-types", "../parser/yaml-documents", "yaml"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.YAMLDocumentSymbols = void 0; const vscode_languageserver_types_1 = require("vscode-languageserver-types"); const yaml_documents_1 = require("../parser/yaml-documents"); const yaml_1 = require("yaml"); class YAMLDocumentSymbols { constructor(telemetry) { this.telemetry = telemetry; } findDocumentSymbols(document, context = { resultLimit: Number.MAX_VALUE }) { let results = []; try { const doc = yaml_documents_1.yamlDocumentsCache.getYamlDocument(document); if (!doc || doc.documents.length === 0) { return null; } for (const yamlDoc of doc.documents) { if (yamlDoc.root) { results = results.concat(this.findFlatDocumentSymbols(document, yamlDoc.root, context)); } } } catch (err) { this.telemetry?.sendError('yaml.documentSymbols.error', err); } return results; } findHierarchicalDocumentSymbols(document, context = { resultLimit: Number.MAX_VALUE }) { let results = []; try { const doc = yaml_documents_1.yamlDocumentsCache.getYamlDocument(document); if (!doc || doc.documents.length === 0) { return null; } for (const yamlDoc of doc.documents) { if (yamlDoc.root) { results = results.concat(this.findHierarchicalSymbols(document, yamlDoc.root, context)); } } } catch (err) { this.telemetry?.sendError('yaml.hierarchicalDocumentSymbols.error', err); } return results; } findFlatDocumentSymbols(document, root, context) { let limit = context.resultLimit || Number.MAX_VALUE; const toVisit = [{ node: root, containerName: '' }]; let nextToVisit = 0; let limitExceeded = false; const result = []; const collectOutlineEntries = (node, containerName) => { if (node.type === 'array') { node.items.forEach((item) => { if (item) { toVisit.push({ node: item, containerName }); } }); } else if (node.type === 'object') { node.properties.forEach((property) => { const valueNode = property.valueNode; if (!valueNode) { return; } if (limit > 0) { limit--; const location = vscode_languageserver_types_1.Location.create(document.uri, getRange(document, property)); const childContainerName = containerName ? containerName + '.' + property.keyNode.value : property.keyNode.value; result.push({ name: getKeyLabel(property), kind: getSymbolKind(valueNode.type), location, containerName, }); toVisit.push({ node: valueNode, containerName: childContainerName }); } else { limitExceeded = true; } }); } }; while (nextToVisit < toVisit.length) { const next = toVisit[nextToVisit++]; collectOutlineEntries(next.node, next.containerName); } if (limitExceeded) { context.onResultLimitExceeded?.(document.uri); } return result; } findHierarchicalSymbols(document, root, context) { let limit = context.resultLimit || Number.MAX_VALUE; const result = []; const toVisit = [{ node: root, result }]; let nextToVisit = 0; let limitExceeded = false; const collectOutlineEntries = (node, result) => { if (node.type === 'array') { node.items.forEach((item, index) => { if (!item) { return; } if (limit > 0) { limit--; const range = getRange(document, item); const symbol = { name: String(index), kind: getSymbolKind(item.type), range, selectionRange: range, children: [], }; result.push(symbol); toVisit.push({ result: symbol.children, node: item }); } else { limitExceeded = true; } }); } else if (node.type === 'object') { node.properties.forEach((property) => { const valueNode = property.valueNode; if (!valueNode) { return; } if (limit > 0) { limit--; const children = []; const symbol = { name: getKeyLabel(property), kind: getSymbolKind(valueNode.type), range: getRange(document, property), selectionRange: getRange(document, property.keyNode), children, detail: getDetail(valueNode), }; result.push(symbol); toVisit.push({ result: children, node: valueNode }); } else { limitExceeded = true; } }); } }; while (nextToVisit < toVisit.length) { const next = toVisit[nextToVisit++]; collectOutlineEntries(next.node, next.result); } if (limitExceeded) { context.onResultLimitExceeded?.(document.uri); } return result; } } exports.YAMLDocumentSymbols = YAMLDocumentSymbols; function getSymbolKind(nodeType) { switch (nodeType) { case 'object': return vscode_languageserver_types_1.SymbolKind.Module; case 'string': return vscode_languageserver_types_1.SymbolKind.String; case 'number': return vscode_languageserver_types_1.SymbolKind.Number; case 'array': return vscode_languageserver_types_1.SymbolKind.Array; case 'boolean': return vscode_languageserver_types_1.SymbolKind.Boolean; default: return vscode_languageserver_types_1.SymbolKind.Variable; } } function getKeyLabel(property) { const keyNode = property.keyNode.internalNode; let name; if ((0, yaml_1.isMap)(keyNode)) { name = '{}'; } else if ((0, yaml_1.isSeq)(keyNode)) { name = '[]'; } else if ('source' in keyNode && typeof keyNode.source === 'string') { name = keyNode.source; } else { name = property.keyNode.value; } if (name) { name = name.replace(/[\n]/g, '↵'); } if (name && name.trim()) { return name; } return `"${name}"`; } function getDetail(node) { if (!node) { return undefined; } if (node.type === 'boolean' || node.type === 'number' || node.type === 'null' || node.type === 'string') { return String(node.value); } if (node.type === 'array') { return node.children.length ? undefined : '[]'; } if (node.type === 'object') { return node.children.length ? undefined : '{}'; } return undefined; } function getRange(document, node) { return vscode_languageserver_types_1.Range.create(document.positionAt(node.offset), document.positionAt(node.offset + node.length)); } }); //# sourceMappingURL=documentSymbols.js.map