import { URI } from 'vscode-uri' ; import * as lsp from 'vscode-languageserver' ; import { Range , Id } from 'lsif-protocol' ; import { FileType , FileSystem , DocumentInfo , FileStat } from './files' ; export interface UriTransformer { toDatabase ( uri ) : string ; fromDatabase ( uri ) : string ; } export const noopTransformer = { toDatabase : uri => uri , fromDatabase : uri => uri } ; export abstract class Database { private fileSystem ! : FileSystem ; private uriTransformer ! : UriTransformer ; protected constructor ( ) { } protected initialize ( transformerFactory ) { const workspaceRoot = this . getWorkspaceRoot ( ) . toString ( true ) ; this . uriTransformer = transformerFactory ? transformerFactory ( workspaceRoot ) : noopTransformer ; this . fileSystem = new FileSystem ( workspaceRoot , this . getDocumentInfos ( ) ) ; } public abstract load ( file , transformerFactory ) ; public abstract close ( ) ; public abstract getWorkspaceRoot ( ) ; protected abstract getDocumentInfos ( ) ; public stat ( uri ) { let transformed = this . uriTransformer . toDatabase ( uri ) ; let result = this . fileSystem . stat ( transformed ) ; if ( result !== null ) { return result ; } let id = this . findFile ( transformed ) ; if ( id === undefined ) { return null ; } return FileStat . createFile ( ) ; } public readDirectory ( uri ) { return this . fileSystem . readDirectory ( this . uriTransformer . toDatabase ( uri ) ) ; } public readFileContent ( uri ) { let transformed = this . uriTransformer . toDatabase ( uri ) ; let info = this . fileSystem . getFileInfo ( transformed ) ; if ( info === undefined ) { info = this . findFile ( transformed ) ; } if ( info === undefined ) { return null ; } let result = this . fileContent ( info ) ; if ( result === undefined ) { return null ; } return result ; } protected abstract findFile ( uri ) ; protected abstract fileContent ( info ) ; public abstract foldingRanges ( uri ) ; public abstract documentSymbols ( uri ) ; public abstract hover ( uri , position ) ; public abstract declarations ( uri , position ) ; public abstract definitions ( uri , position ) ; public abstract references ( uri , position , context ) ; protected asDocumentSymbol ( range ) { let tag = range . tag ; if ( tag === undefined || ! ( tag . type === 'declaration' || tag . type === 'definition' ) ) { return undefined ; } return lsp . DocumentSymbol . create ( tag . text , tag . detail || '' , tag . kind , tag . fullRange , this . asRange ( range ) ) ; } protected asRange ( value ) { return { start : { line : value . start . line , character : value . start . character } , end : { line : value . end . line , character : value . end . character } } ; } protected toDatabase ( uri ) { return this . uriTransformer . toDatabase ( uri ) ; } protected fromDatabase ( uri ) { return this . uriTransformer . fromDatabase ( uri ) ; } }