UNPKG

atom-languageclient

Version:
89 lines (82 loc) 3.62 kB
import type * as atomIde from "atom-ide-base" import Convert from "../convert" import { Point, TextEditor } from "atom" import { LanguageClientConnection, Location, ServerCapabilities, ReferenceParams } from "../languageclient" /** * Public: Adapts the language server definition provider to the Atom IDE UI Definitions package for 'Go To Definition' * functionality. */ export default class FindReferencesAdapter { /** * Public: Determine whether this adapter can be used to adapt a language server based on the serverCapabilities * matrix containing a referencesProvider. * * @param serverCapabilities The {ServerCapabilities} of the language server to consider. * @returns A {Boolean} indicating adapter can adapt the server based on the given serverCapabilities. */ public static canAdapt(serverCapabilities: ServerCapabilities): boolean { return serverCapabilities.referencesProvider === true } /** * Public: Get the references for a specific symbol within the document as represented by the {TextEditor} and {Point} * within it via the language server. * * @param connection A {LanguageClientConnection} to the language server that will be queried for the references. * @param editor The Atom {TextEditor} containing the text the references should relate to. * @param point The Atom {Point} containing the point within the text the references should relate to. * @returns A {Promise} containing a {FindReferencesReturn} with all the references the language server could find. */ public async getReferences( connection: LanguageClientConnection, editor: TextEditor, point: Point, projectRoot: string | null ): Promise<atomIde.FindReferencesReturn | null> { const locations = await connection.findReferences(FindReferencesAdapter.createReferenceParams(editor, point)) if (locations == null) { return null } const references: atomIde.Reference[] = locations.map(FindReferencesAdapter.locationToReference) return { type: "data", baseUri: projectRoot || "", referencedSymbolName: FindReferencesAdapter.getReferencedSymbolName(editor, point, references), references, } } /** * Public: Create a {ReferenceParams} from a given {TextEditor} for a specific {Point}. * * @param editor A {TextEditor} that represents the document. * @param point A {Point} within the document. * @returns A {ReferenceParams} built from the given parameters. */ public static createReferenceParams(editor: TextEditor, point: Point): ReferenceParams { return { textDocument: Convert.editorToTextDocumentIdentifier(editor), position: Convert.pointToPosition(point), context: { includeDeclaration: true }, } } /** * Public: Convert a {Location} into a {Reference}. * * @param location A {Location} to convert. * @returns A {Reference} equivalent to the given {Location}. */ public static locationToReference(location: Location): atomIde.Reference { return { uri: Convert.uriToPath(location.uri), name: null, range: Convert.lsRangeToAtomRange(location.range), } } /** Public: Get a symbol name from a {TextEditor} for a specific {Point} in the document. */ public static getReferencedSymbolName(editor: TextEditor, point: Point, references: atomIde.Reference[]): string { if (references.length === 0) { return "" } const currentReference = references.find((r) => r.range.containsPoint(point)) || references[0] return editor.getBuffer().getTextInRange(currentReference.range) } }