1- import * as vscode from "vscode"
2- import * as messages from "./messages"
3- import { compileAndRunQueryAgainstDatabase , QueryWithResults } from "./run-queries" ;
4- import { QueryServerClient } from "./queryserver-client" ;
5- import { DatabaseManager , DatabaseItem } from "./databases" ;
6- import { CodeQLCliServer } from "./cli" ;
7- import { getResultSetSchema , UrlValue , LineColumnLocation , EntityValue } from "./bqrs-cli-types" ;
1+ import * as fs from 'fs-extra' ;
2+ import * as yaml from 'js-yaml' ;
3+ import * as tmp from 'tmp' ;
4+ import * as vscode from "vscode" ;
85import { decodeSourceArchiveUri , zipArchiveScheme } from "./archive-filesystem-provider" ;
6+ import { EntityValue , getResultSetSchema , LineColumnLocation , UrlValue } from "./bqrs-cli-types" ;
7+ import { CodeQLCliServer } from "./cli" ;
8+ import { DatabaseItem , DatabaseManager } from "./databases" ;
9+ import * as helpers from './helpers' ;
10+ import * as messages from "./messages" ;
11+ import { QueryServerClient } from "./queryserver-client" ;
12+ import { compileAndRunQueryAgainstDatabase , QueryWithResults } from "./run-queries" ;
913
1014const TEMPLATE_NAME = "selectedSourceFile" ;
1115const SELECT_QUERY_NAME = "#select" ;
@@ -14,22 +18,46 @@ enum KeyType {
1418 DefinitionQuery , ReferenceQuery
1519}
1620
17- async function resolveQueries ( keyType : KeyType ) : Promise < string [ ] > {
21+ function tagOfKeyType ( keyType : KeyType ) : string {
1822 switch ( keyType ) {
19- case KeyType . DefinitionQuery : return [ "/home/jcreed/semmle/code/ql/cpp/ql/src/localDefinitions.ql" ]
20- case KeyType . ReferenceQuery : return [ "/home/jcreed/semmle/code/ql/cpp/ql/src/localReferences.ql" ]
23+ case KeyType . DefinitionQuery : return "local-definitions" ;
24+ case KeyType . ReferenceQuery : return "local-references" ;
2125 }
2226}
2327
24- export function createDefinitionsHandler ( cli : CodeQLCliServer , qs : QueryServerClient , dbm : DatabaseManager ) : vscode . DefinitionProvider {
28+ async function resolveQueries ( cli : CodeQLCliServer , qlpack : string , keyType : KeyType ) : Promise < string [ ] > {
29+ const suiteFile = tmp . fileSync ( { postfix : '.qls' } ) . name ;
30+ const suiteYaml = { qlpack, include : { kind : 'definitions' , 'tags contain' : tagOfKeyType ( keyType ) } } ;
31+ await fs . writeFile ( suiteFile , yaml . safeDump ( suiteYaml ) , 'utf8' ) ;
32+
33+ const queries = await cli . resolveQueriesInSuite ( suiteFile , helpers . getOnDiskWorkspaceFolders ( ) ) ;
34+ if ( queries . length === 0 ) {
35+ throw new Error ( "Couldn't find any queries for qlpack" ) ;
36+ }
37+ return queries ;
38+ }
39+
40+ async function qlpackOfDatabase ( cli : CodeQLCliServer , db : DatabaseItem ) : Promise < string | undefined > {
41+ if ( db . contents === undefined )
42+ return undefined ;
43+ const datasetPath = db . contents . datasetUri . fsPath ;
44+ const { qlpack } = await helpers . resolveDatasetFolder ( cli , datasetPath ) ;
45+ return qlpack ;
46+ }
47+
48+ export async function createDefinitionsHandler ( cli : CodeQLCliServer , qs : QueryServerClient , dbm : DatabaseManager ) : Promise < vscode . DefinitionProvider > {
2549 let fileCache = new CachedOperation < vscode . LocationLink [ ] > ( async ( uriString : string ) => {
2650 const uri = decodeSourceArchiveUri ( vscode . Uri . parse ( uriString ) ) ;
2751 const sourceArchiveUri = vscode . Uri . file ( uri . sourceArchiveZipPath ) . with ( { scheme : zipArchiveScheme } ) ;
2852
2953 const db = dbm . findDatabaseItemBySourceArchive ( sourceArchiveUri ) ;
3054 if ( db ) {
55+ const qlpack = await qlpackOfDatabase ( cli , db ) ;
56+ if ( qlpack === undefined ) {
57+ throw new Error ( "Can't infer qlpack from database source archive" ) ;
58+ }
3159 const links : vscode . DefinitionLink [ ] = [ ]
32- for ( const query of await resolveQueries ( KeyType . DefinitionQuery ) ) {
60+ for ( const query of await resolveQueries ( cli , qlpack , KeyType . DefinitionQuery ) ) {
3361 const templates : messages . TemplateDefinitions = {
3462 [ TEMPLATE_NAME ] : {
3563 values : {
@@ -69,15 +97,19 @@ interface FullLocationLink extends vscode.LocationLink {
6997 originUri : vscode . Uri ;
7098}
7199
72- export function createReferencesHander ( cli : CodeQLCliServer , qs : QueryServerClient , dbm : DatabaseManager ) : vscode . ReferenceProvider {
100+ export async function createReferencesHander ( cli : CodeQLCliServer , qs : QueryServerClient , dbm : DatabaseManager ) : Promise < vscode . ReferenceProvider > {
73101 let fileCache = new CachedOperation < FullLocationLink [ ] > ( async ( uriString : string ) => {
74102 const uri = decodeSourceArchiveUri ( vscode . Uri . parse ( uriString ) ) ;
75103 const sourceArchiveUri = vscode . Uri . file ( uri . sourceArchiveZipPath ) . with ( { scheme : zipArchiveScheme } ) ;
76104
77105 const db = dbm . findDatabaseItemBySourceArchive ( sourceArchiveUri ) ;
78106 if ( db ) {
107+ const qlpack = await qlpackOfDatabase ( cli , db ) ;
108+ if ( qlpack === undefined ) {
109+ throw new Error ( "Can't infer qlpack from database source archive" ) ;
110+ }
79111 const links : FullLocationLink [ ] = [ ]
80- for ( const query of await resolveQueries ( KeyType . ReferenceQuery ) ) {
112+ for ( const query of await resolveQueries ( cli , qlpack , KeyType . ReferenceQuery ) ) {
81113 const templates : messages . TemplateDefinitions = {
82114 [ TEMPLATE_NAME ] : {
83115 values : {
0 commit comments