'use strict' ; import { IPCMessageReader , IPCMessageWriter , RequestHandler , Definition , Location , ResponseError , createConnection , IConnection , TextDocumentSyncKind , TextDocuments , TextDocument , Diagnostic , DiagnosticSeverity , InitializeParams , InitializeResult , TextDocumentPositionParams , CompletionItem , CompletionItemKind , Range } from 'vscode-languageserver' ; import { } from 'cancellation' ; import * as vscodels from 'vscode-languageserver' ; import { File } from './filehandler' ; import * as p from 'path' ; import * as enumerable from 'linq-es5' ; const controllerFileEx = "\\.controller\\.(js|ts)$" ; let connection = createConnection ( new IPCMessageReader ( process ) , new IPCMessageWriter ( process ) ) ; let documents = new TextDocuments ( ) ; documents . listen ( connection ) ; export var workspaceRoot ; connection . onInitialize ( ( params ) : InitializeResult => { connection . console . info ( "Initializing UI5 XML language server" ) ; workspaceRoot = params . rootPath ; return { capabilities : { textDocumentSync : documents . syncKind , definitionProvider : true , completionProvider : { resolveProvider : true , triggerCharacters : [ '.' ] } } } ; } ) ; connection . onDefinition ( ( params ) => { return [ ] ; } ) ; documents . onDidChangeContent ( change => { let diag = [ ] ; let text = change . document . getText ( ) ; let jcontent = JSON . parse ( text ) ; let targets = enumerable . AsEnumerable ( getTargets ( jcontent ) ) ; for ( let route of jcontent [ "sap.ui5" ] . routing . routes ) { if ( ! targets . Contains ( route . target ) ) diag . push ( { message : "Target '" + route . target + "' could not be found." , range : getRange ( text , new RegExp ( route . name ) ) [ 0 ] , severity : 1 , source : route . name } ) ; } connection . sendDiagnostics ( { uri : change . document . uri , diagnostics : diag } ) ; } ) ; function getTargets ( jcontent ) { let targetnames = [ ] ; for ( let key in jcontent [ "sap.ui5" ] . routing . targets ) targetnames . push ( key ) ; return targetnames ; } function tryOpenEventHandler ( line , positionInLine , documentText ) { let rightpart = line . substr ( positionInLine ) . match ( /(\w*?)"/ ) [ 1 ] ; if ( ! rightpart ) return null ; let leftpart = line . substr ( 0 , positionInLine ) ; let leftquotepos = leftpart . match ( /.*"/ ) [ 0 ] . length ; if ( ! leftquotepos ) return ; leftpart = leftpart . substr ( leftquotepos ) ; let name = leftpart + rightpart ; let cnameri = documentText . match ( /controllerName="([\w\.]+)"/ ) ; if ( ! cnameri ) { return [ ] ; } let cname = cnameri [ 1 ] . split ( "." ) . pop ( ) ; let files = File . find ( new RegExp ( cname + controllerFileEx ) ) ; let foundControllers = [ ] ; let ret = [ ] ; for ( let i = 0 ; i < files . length ; i = i + 2 ) { let f = files . length > 1 ? files [ i + 1 ] : files [ i ] ; foundControllers . push ( { range : { start : { character : 0 , line : 0 } , end : { character : 0 , line : 0 } } , uri : "file:///" + f } ) ; } for ( let entry of foundControllers ) { let txt = File . open ( entry . uri . substr ( 8 ) ) ; let matchRegex = new RegExp ( name + /\s*?\(.*?\)/ . source , "g" ) ; let ranges = getRange ( txt , matchRegex ) ; if ( ranges . length > 0 ) for ( let r of ranges ) ret . push ( { uri : entry . uri , range : r } ) ; } return ret ; } documents . onDidChangeContent ( ( e ) => { connection . console . info ( "Did  Change Content Event occurred." ) ; } ) ; connection . listen ( ) ; function getRange ( docText , searchPattern ) { const lineRegex = /.*(?:\n|\r\n)/gm ; let l ; let ret = [ ] ; let linectr = 0 ; while ( ( l = lineRegex . exec ( docText ) ) !== null ) { linectr = linectr + 1 ; if ( l . index === lineRegex . lastIndex ) lineRegex . lastIndex ++ ; let match = searchPattern . exec ( l ) ; if ( ! match ) continue ; ret . push ( { start : { line : linectr , character : match . index } , end : { line : linectr , character : match . index + match [ 0 ] . length } , } ) ; } return ret ; } function getLine ( input , startindex ) { let rightpart = input . substr ( startindex ) . match ( /.*/m ) [ 0 ] ; if ( ! rightpart ) return null ; const getLastLineRegex = /\n.*/gm ; let leftinput = input . substr ( 0 , startindex ) ; let l , m ; while ( ( l = getLastLineRegex . exec ( leftinput ) ) !== null ) { if ( l . index === getLastLineRegex . lastIndex ) getLastLineRegex . lastIndex ++ ; m = l ; } let leftpart = m . pop ( ) . substr ( 1 ) ; if ( ! leftpart ) return null ; return leftpart + rightpart ; }