const lodash = require ( "lodash" ) ; import { RefractSymbolMap } from './refractSymbolMap' ; import { Range , SymbolInformation } from 'vscode-languageserver' ; export function createLineReferenceFromSourceMap ( refractSourceMap , document , documentLines ) { const firstSourceMap = lodash . first ( refractSourceMap ) ; if ( typeof ( firstSourceMap ) === 'undefined' ) { return { endIndex : documentLines [ documentLines . length - 1 ] . length , endRow : documentLines . length - 1 , startIndex : 0 , startRow : 0 , } ; } const sourceMapArray = lodash . map ( firstSourceMap . content , ( sm ) => { return { charCount : lodash . last ( sm ) , charIndex : lodash . head ( sm ) , } ; } ) ; const sourceMap = lodash . head ( sourceMapArray ) ; const sourceSubstring = document . substring ( sourceMap . charIndex , sourceMap . charIndex + sourceMap . charCount ) ; const sourceLines = sourceSubstring . split ( /\r?\n/g ) ; if ( sourceSubstring === '\n' || sourceSubstring === '\r' ) { return { endIndex : lodash . last ( documentLines ) . length , endRow : documentLines . length , startIndex : 0 , startRow : 0 , } ; } const startRow = document . substring ( 0 , sourceMap . charIndex ) . split ( /\r?\n/g ) . length - 1 ; const endRow = startRow + sourceLines . length - 1 ; const startIndex = documentLines [ startRow ] . indexOf ( lodash . head ( sourceLines ) ) ; const endIndex = documentLines [ endRow ] . length ; return { startRow , endRow , startIndex , endIndex , } ; } export function query ( element , elementQueries , container = '' ) { if ( ! element . content ) { return [ ] ; } if ( ! lodash . isArray ( element . content ) ) { return [ ] ; } const arrayOfArrayOfResults = lodash . map ( elementQueries , ( elementQuery ) => { const filterResult = lodash . filter ( element . content , elementQuery . query ) ; lodash . forEach ( filterResult , ( res ) => { res . symbolKind = elementQuery . symbolKind ; res . container = container ; } ) ; return filterResult ; } ) ; const results = lodash . flatten ( arrayOfArrayOfResults ) ; return lodash . chain ( element . content ) . map ( ( nestedElement ) => { return query ( nestedElement , elementQueries , decodeURI ( lodash . get ( nestedElement , 'meta.title.content' , lodash . get ( nestedElement , 'attributes.href.content' , lodash . get ( nestedElement , 'meta.title' ) ) ) ) ) ; } ) . flatten ( ) . concat ( results ) . value ( ) ; } export function extractSymbols ( element , document , documentLines , symbolsType ) { const queryResults = query ( element , symbolsType ) ; return lodash . transform ( queryResults , ( result , queryResult ) => { let sourceMap ; [ 'meta.title.attributes.sourceMap' , 'attributes.href.attributes.sourceMap' , ( qs ) => query ( qs , [ { query : { attributes : { method : { } } } , symbolKind : 0 } ] ) , ] . some ( ( path ) : boolean => { if ( typeof ( path ) === 'function' ) { sourceMap = lodash . get ( ( path as Function ) ( queryResult ) [ 0 ] , 'attributes.method.attributes.sourceMap' ) ; return true ; } else { if ( lodash . has ( queryResult , path ) ) { sourceMap = lodash . get ( queryResult , path ) ; return true ; } } } ) ; const lineReference = createLineReferenceFromSourceMap ( sourceMap , document , documentLines ) ; let description = '' ; [ 'meta.title.content' , 'attributes.href.content' , ( qs ) => query ( qs , [ { query : { attributes : { method : { } } } , symbolKind : 0 } ] ) , ] . some ( ( path ) : boolean => { if ( typeof ( path ) === 'function' ) { description = decodeURI ( lodash . get ( ( path as Function ) ( queryResult ) [ 0 ] , 'attributes.method.content' ) ) ; return true ; } else { if ( lodash . has ( queryResult , path ) ) { description = decodeURI ( lodash . get ( queryResult , path ) ) ; return true ; } } } ) ; if ( ! lodash . isEmpty ( lineReference ) ) { result . push ( SymbolInformation . create ( description , queryResult . symbolKind , Range . create ( lineReference . startRow , lineReference . startIndex , lineReference . endRow , lineReference . endIndex ) , null , queryResult . container ) ) ; } } ) ; }