import { Set } from 'typescript-collections' ; import * as vscode from 'vscode' ; import { ExtensionComponent } from '../extensionComponent' ; import { DependenciesTreeNode } from '../treeDataProviders/dependenciesTree/dependenciesTreeNode' ; import { TreesManager } from '../treeDataProviders/treesManager' ; import { IIssueCacheObject } from '../types/issueCacheObject' ; import { IIssueKey } from '../types/issueKey' ; import { ILicenseKey } from '../types/licenseKey' ; import { Severity , SeverityUtils } from '../types/severity' ; see HoverManager export abstract class AbstractHoverProvider implements vscode . HoverProvider , ExtensionComponent { constructor ( protected _documentSelector , protected _treesManager ) { } param document param cursorPosition returns public abstract getNodeByLocation ( document , cursorPosition ) ; public activate ( context ) { context . subscriptions . push ( vscode . languages . registerHoverProvider ( this . _documentSelector , this ) ) ; } param document param position public provideHover ( document , position ) { let node = this . getNodeByLocation ( document , position ) ; if ( ! node ) { return ; } return new vscode . Hover ( new vscode . MarkdownString ( this . getDetailsFromXray ( node ) ) ) ; } private licensesToMarkdown ( licenses ) { let markDownSyntax = [ ] ; licenses . forEach ( licenseKey => { markDownSyntax . push ( licenseKey . licenseName ) ; } ) ; return markDownSyntax ; } private getDetailsFromXray ( node ) { let xrayText = '### Details from Xray:\n\n' ; if ( node . topSeverity !== Severity . Normal ) { xrayText += '**Vulnerabilities**: ' + this . getIssueSummary ( node . issues ) ; } let violatedLicenses = node . getViolatedLicenses ( ) ; if ( violatedLicenses . size > 0 ) { xrayText += '\n\n**Transitive Violated Licenses**: ' + this . getViolatedLicenseInfo ( violatedLicenses ) ; } return xrayText + '\n\n' + this . createLicensesText ( this . licensesToMarkdown ( node . licenses ) ) ; } private getViolatedLicenseInfo ( violatedLicenses ) { let summary = '' ; for ( let violatedLicense of violatedLicenses . keys ( ) ) { summary += violatedLicense + ', ' ; } return summary . substring ( 0 , summary . length - 2 ) + '\n\n' ; } private createLicensesText ( licenses ) { return `${ licenses ? `**Licenses**: ${ licenses }\n\n` : '\n\n' }` ; } private getIssueSummary ( issues ) { if ( ! issues ) { return '' ; } let summary = '' ; let totalNumOfSeverities = new Array < number > ( Object . keys ( Severity ) . length / 2 ) ; issues . forEach ( issueId => { let issue = this . _treesManager . scanCacheManager . getIssue ( issueId . issue_id ) ; if ( issue ) { totalNumOfSeverities [ issue . severity ] = totalNumOfSeverities [ issue . severity ] ? totalNumOfSeverities [ issue . severity ] + 1 : 1 ; } } ) ; for ( let i = totalNumOfSeverities . length - 1 ; i >= 0 ; i -- ) { if ( ! totalNumOfSeverities [ i ] ) { continue ; } summary += `![severity.icon](${ SeverityUtils . getIcon ( i , true ) }) ${ SeverityUtils . getString ( i ) } (${ totalNumOfSeverities [ i ] })  &nbsp;` ; } return summary ; } }