'use strict' ; import { Diagnostic , DiagnosticSeverity , IConnection , InitializeResult , IPCMessageReader , IPCMessageWriter , Range , RequestType , ServerCapabilities , TextDocument , TextDocuments , createConnection , } from 'vscode-languageserver' ; import { parse } from './parser' ; import { defaultRefractSymbolsTree } from './refractSymbolMap' ; import * as refractUtils from './refractUtils' ; import { ApiElementsSettings } from './structures' ; import { utf16to8 } from './utfUtils' ; const lodash = require ( 'lodash' ) ; const apiDescriptionMixins = require ( 'lodash-api-description' ) ; const refractDocuments = new Map ( ) ; apiDescriptionMixins ( lodash ) ; let debouncedValidateTextDocument = validateTextDocument ; const getHelpUrl = ( section ) : string => { return `https://github.com/XVincentX/vscode-apielements/blob/master/TROUBLESHOT.md${ section }` ; } ; const connection = createConnection ( new IPCMessageReader ( process ) , new IPCMessageWriter ( process ) ) ; const documents = new TextDocuments ( ) ; documents . listen ( connection ) ; let workspaceRoot ; connection . onInitialize ( ( params ) : InitializeResult => { workspaceRoot = params . rootPath ; const capabilities = { documentSymbolProvider : true , textDocumentSync : documents . syncKind , } ; return { capabilities , } as InitializeResult ; } ) ; documents . onDidChangeContent ( ( change ) => { debouncedValidateTextDocument ( change . document ) ; } ) ; documents . onDidClose ( ( event ) => { connection . sendDiagnostics ( { diagnostics : [ ] , uri : event . document . uri } ) ; } ) ; let currentSettings ; let desideredSymbols = defaultRefractSymbolsTree ; connection . onDidChangeConfiguration ( ( change ) => { const apiElementsSettings = change . settings . apiElements ; currentSettings = lodash . cloneDeep ( apiElementsSettings ) ; debouncedValidateTextDocument = lodash . debounce ( validateTextDocument , apiElementsSettings . validation . debounce ) ; const desideredSymbolNames = Object . keys ( apiElementsSettings . symbols ) . filter ( ( sym ) => apiElementsSettings . symbols [ sym ] === true ) ; desideredSymbols = defaultRefractSymbolsTree . filter ( ( sym ) => lodash . includes ( desideredSymbolNames , sym . friendlyName ) ) ; documents . all ( ) . forEach ( validateTextDocument ) ; } ) ; function validateTextDocument ( textDocument ) { const diagnostics = [ ] ; const text = textDocument . getText ( ) ; parse ( text , currentSettings . parser ) . then ( ( output ) => output , ( error ) => error . result ) . then ( ( refractOutput ) => { refractDocuments . set ( textDocument . uri . toString ( ) , refractOutput ) ; const annotations = lodash . filterContent ( refractOutput , { element : 'annotation' } ) ; const utf8Text = utf16to8 ( text ) ; const documentLines = utf8Text . split ( /\r?\n/g ) ; lodash . forEach ( annotations , ( annotation ) => { const lineReference = refractUtils . createLineReferenceFromSourceMap ( annotation . attributes . sourceMap , text , documentLines ) ; diagnostics . push ( { code : annotation . attributes . code , message : annotation . content , range : Range . create ( lineReference . startRow , lineReference . startIndex , lineReference . endRow , lineReference . endIndex ) , severity : ( ( lodash . head ( annotation . meta . classes ) === 'warning' ) ? DiagnosticSeverity . Warning : DiagnosticSeverity . Error ) , source : 'fury' , } as Diagnostic ) ; } ) ; connection . sendDiagnostics ( { uri : textDocument . uri , diagnostics } ) ; } ) ; } connection . onDocumentSymbol ( ( symbolParam ) => { try { if ( currentSettings . parser . exportSourcemap === false ) { connection . window . showWarningMessage ( '\
        The current parser options have source maps disabled.\
        Without those, it\'s not possible to generate document symbol.\
        ' , { title : 'More Info' } ) . then ( ( ) => { connection . sendNotification ( 'openUrl' , getHelpUrl ( '#no-sourcemaps-enabled' ) ) ; } ) ; return Promise . resolve ( [ ] ) ; } const documentObject = documents . get ( symbolParam . textDocument . uri ) ; let textDocument = documentObject . getText ( ) ; if ( documentObject . languageId === 'apiblueprint' ) { textDocument = utf16to8 ( textDocument ) ; } const documentLines = textDocument . split ( /\r?\n/g ) ; const refractOutput = refractDocuments . get ( symbolParam . textDocument . uri . toString ( ) ) ; if ( typeof ( refractOutput ) === 'undefined' ) { return parse ( textDocument , currentSettings . parser ) . then ( ( output ) => { refractDocuments . set ( symbolParam . textDocument . uri . toString ( ) , output ) ; return refractUtils . extractSymbols ( output , textDocument , documentLines , desideredSymbols ) ; } ) ; } const symbolArray = refractUtils . extractSymbols ( refractOutput , textDocument , documentLines , desideredSymbols ) ; return Promise . resolve ( symbolArray ) ; } catch ( err ) { connection . window . showErrorMessage ( err . message ) ; } } ) ; connection . onRequest ( 'parserOutput' , ( code ) => { return parse ( code , currentSettings . parser ) ; } ) ; connection . listen ( ) ;