UNPKG

langium

Version:

A language engineering tool for the Language Server Protocol

85 lines 3.51 kB
/****************************************************************************** * 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 } from '../utils/cancellation.js'; import { isMultiReference, isReference } from '../syntax-tree.js'; import { getDocument, streamAst, streamReferences } from '../utils/ast-utils.js'; import { toDocumentSegment } from '../utils/cst-utils.js'; import { interruptAndCheck } from '../utils/promise-utils.js'; import { UriUtils } from '../utils/uri-utils.js'; export class DefaultAstNodeDescriptionProvider { constructor(services) { this.astNodeLocator = services.workspace.AstNodeLocator; this.nameProvider = services.references.NameProvider; } createDescription(node, name, document) { const doc = document ?? getDocument(node); name ?? (name = this.nameProvider.getName(node)); const path = this.astNodeLocator.getAstNodePath(node); if (!name) { throw new Error(`Node at path ${path} has no name.`); } let nameNodeSegment; const nameSegmentGetter = () => nameNodeSegment ?? (nameNodeSegment = toDocumentSegment(this.nameProvider.getNameNode(node) ?? node.$cstNode)); return { node, name, get nameSegment() { return nameSegmentGetter(); }, selectionSegment: toDocumentSegment(node.$cstNode), type: node.$type, documentUri: doc.uri, path }; } } export class DefaultReferenceDescriptionProvider { constructor(services) { this.nodeLocator = services.workspace.AstNodeLocator; } async createDescriptions(document, cancelToken = CancellationToken.None) { const descr = []; const rootNode = document.parseResult.value; for (const astNode of streamAst(rootNode)) { await interruptAndCheck(cancelToken); streamReferences(astNode).forEach(refInfo => { if (!refInfo.reference.error) { descr.push(...this.createInfoDescriptions(refInfo)); } }); } return descr; } createInfoDescriptions(refInfo) { const reference = refInfo.reference; if (reference.error || !reference.$refNode) { return []; } let items = []; if (isReference(reference) && reference.$nodeDescription) { items = [reference.$nodeDescription]; } else if (isMultiReference(reference)) { items = reference.items.map(e => e.$nodeDescription).filter(e => e !== undefined); } const sourceUri = getDocument(refInfo.container).uri; const sourcePath = this.nodeLocator.getAstNodePath(refInfo.container); const descriptions = []; const segment = toDocumentSegment(reference.$refNode); for (const item of items) { descriptions.push({ sourceUri, sourcePath, targetUri: item.documentUri, targetPath: item.path, segment, local: UriUtils.equals(item.documentUri, sourceUri) }); } return descriptions; } } //# sourceMappingURL=ast-descriptions.js.map