@@ -12,140 +12,130 @@ import {
1212 ModeledMethodWithSignature ,
1313} from "./modeled-method" ;
1414
15- class FlowModelGenerator {
16- constructor (
17- private readonly cli : CodeQLCliServer ,
18- private readonly queryRunner : QueryRunner ,
19- private readonly queryStorageDir : string ,
20- private readonly qlDir : string ,
21- private readonly databaseItem : DatabaseItem ,
22- private readonly progress : ProgressCallback ,
23- private readonly token : CancellationToken ,
24- ) { }
25-
26- private async getModeledMethodsFromFlow (
27- type : Exclude < ModeledMethodType , "none" > ,
28- queryName : string ,
29- queryStep : number ,
30- ) : Promise < ModeledMethodWithSignature [ ] > {
31- const definition = extensiblePredicateDefinitions [ type ] ;
32-
33- const query = join (
34- this . qlDir ,
35- this . databaseItem . language ,
36- "ql/src/utils/modelgenerator" ,
37- queryName ,
38- ) ;
15+ type FlowModelOptions = {
16+ cliServer : CodeQLCliServer ;
17+ queryRunner : QueryRunner ;
18+ queryStorageDir : string ;
19+ qlDir : string ;
20+ databaseItem : DatabaseItem ;
21+ progress : ProgressCallback ;
22+ token : CancellationToken ;
23+ onResults : ( results : ModeledMethodWithSignature [ ] ) => void | Promise < void > ;
24+ } ;
25+
26+ async function getModeledMethodsFromFlow (
27+ type : Exclude < ModeledMethodType , "none" > ,
28+ queryName : string ,
29+ queryStep : number ,
30+ {
31+ cliServer,
32+ queryRunner,
33+ queryStorageDir,
34+ qlDir,
35+ databaseItem,
36+ progress,
37+ token,
38+ } : Omit < FlowModelOptions , "onResults" > ,
39+ ) : Promise < ModeledMethodWithSignature [ ] > {
40+ const definition = extensiblePredicateDefinitions [ type ] ;
3941
40- const queryRun = this . queryRunner . createQueryRun (
41- this . databaseItem . databaseUri . fsPath ,
42- { queryPath : query , quickEvalPosition : undefined } ,
43- false ,
44- getOnDiskWorkspaceFolders ( ) ,
45- undefined ,
46- this . queryStorageDir ,
47- undefined ,
48- undefined ,
49- ) ;
42+ const query = join (
43+ qlDir ,
44+ databaseItem . language ,
45+ "ql/src/utils/modelgenerator" ,
46+ queryName ,
47+ ) ;
5048
51- const queryResult = await queryRun . evaluate (
52- ( { step , message } ) =>
53- this . progress ( {
54- message : `Generating ${ type } model: ${ message } ` ,
55- step : queryStep * 1000 + step ,
56- maxStep : 4000 ,
57- } ) ,
58- this . token ,
59- new TeeLogger ( this . queryRunner . logger , queryRun . outputDir . logPath ) ,
60- ) ;
49+ const queryRun = queryRunner . createQueryRun (
50+ databaseItem . databaseUri . fsPath ,
51+ { queryPath : query , quickEvalPosition : undefined } ,
52+ false ,
53+ getOnDiskWorkspaceFolders ( ) ,
54+ undefined ,
55+ queryStorageDir ,
56+ undefined ,
57+ undefined ,
58+ ) ;
6159
62- const bqrsPath = queryResult . outputDir . bqrsPath ;
60+ const queryResult = await queryRun . evaluate (
61+ ( { step, message } ) =>
62+ progress ( {
63+ message : `Generating ${ type } model: ${ message } ` ,
64+ step : queryStep * 1000 + step ,
65+ maxStep : 4000 ,
66+ } ) ,
67+ token ,
68+ new TeeLogger ( queryRunner . logger , queryRun . outputDir . logPath ) ,
69+ ) ;
6370
64- const bqrsInfo = await this . cli . bqrsInfo ( bqrsPath ) ;
65- if ( bqrsInfo [ "result-sets" ] . length !== 1 ) {
66- throw new Error (
67- `Expected exactly one result set, got ${ bqrsInfo [ "result-sets" ] . length } ` ,
68- ) ;
69- }
71+ const bqrsPath = queryResult . outputDir . bqrsPath ;
7072
71- const resultSet = bqrsInfo [ "result-sets" ] [ 0 ] ;
73+ const bqrsInfo = await cliServer . bqrsInfo ( bqrsPath ) ;
74+ if ( bqrsInfo [ "result-sets" ] . length !== 1 ) {
75+ throw new Error (
76+ `Expected exactly one result set, got ${ bqrsInfo [ "result-sets" ] . length } ` ,
77+ ) ;
78+ }
7279
73- const decodedResults = await this . cli . bqrsDecode ( bqrsPath , resultSet . name ) ;
80+ const resultSet = bqrsInfo [ "result-sets" ] [ 0 ] ;
7481
75- const results = decodedResults . tuples ;
82+ const decodedResults = await cliServer . bqrsDecode ( bqrsPath , resultSet . name ) ;
7683
77- return (
78- results
79- // This is just a sanity check. The query should only return strings.
80- . filter ( ( result ) => typeof result [ 0 ] === "string" )
81- . map ( ( result ) => {
82- const row = result [ 0 ] as string ;
84+ const results = decodedResults . tuples ;
8385
84- return definition . readModeledMethod ( row . split ( ";" ) ) ;
85- } )
86- ) ;
86+ return (
87+ results
88+ // This is just a sanity check. The query should only return strings.
89+ . filter ( ( result ) => typeof result [ 0 ] === "string" )
90+ . map ( ( result ) => {
91+ const row = result [ 0 ] as string ;
92+
93+ return definition . readModeledMethod ( row . split ( ";" ) ) ;
94+ } )
95+ ) ;
96+ }
97+
98+ export async function generateFlowModel ( {
99+ onResults,
100+ ...options
101+ } : FlowModelOptions ) {
102+ const summaryResults = await getModeledMethodsFromFlow (
103+ "summary" ,
104+ "CaptureSummaryModels.ql" ,
105+ 0 ,
106+ options ,
107+ ) ;
108+ if ( summaryResults ) {
109+ await onResults ( summaryResults ) ;
87110 }
88111
89- async run (
90- onResults : ( results : ModeledMethodWithSignature [ ] ) => void | Promise < void > ,
91- ) {
92- const summaryResults = await this . getModeledMethodsFromFlow (
93- "summary" ,
94- "CaptureSummaryModels.ql" ,
95- 0 ,
96- ) ;
97- if ( summaryResults ) {
98- await onResults ( summaryResults ) ;
99- }
100-
101- const sinkResults = await this . getModeledMethodsFromFlow (
102- "sink" ,
103- "CaptureSinkModels.ql" ,
104- 1 ,
105- ) ;
106- if ( sinkResults ) {
107- await onResults ( sinkResults ) ;
108- }
109-
110- const sourceResults = await this . getModeledMethodsFromFlow (
111- "source" ,
112- "CaptureSourceModels.ql" ,
113- 2 ,
114- ) ;
115- if ( sourceResults ) {
116- await onResults ( sourceResults ) ;
117- }
118-
119- const neutralResults = await this . getModeledMethodsFromFlow (
120- "neutral" ,
121- "CaptureNeutralModels.ql" ,
122- 3 ,
123- ) ;
124- if ( neutralResults ) {
125- await onResults ( neutralResults ) ;
126- }
112+ const sinkResults = await getModeledMethodsFromFlow (
113+ "sink" ,
114+ "CaptureSinkModels.ql" ,
115+ 1 ,
116+ options ,
117+ ) ;
118+ if ( sinkResults ) {
119+ await onResults ( sinkResults ) ;
127120 }
128- }
129121
130- export async function generateFlowModel (
131- cli : CodeQLCliServer ,
132- queryRunner : QueryRunner ,
133- queryStorageDir : string ,
134- qlDir : string ,
135- databaseItem : DatabaseItem ,
136- onResults : ( results : ModeledMethodWithSignature [ ] ) => void | Promise < void > ,
137- progress : ProgressCallback ,
138- token : CancellationToken ,
139- ) {
140- const generator = new FlowModelGenerator (
141- cli ,
142- queryRunner ,
143- queryStorageDir ,
144- qlDir ,
145- databaseItem ,
146- progress ,
147- token ,
122+ const sourceResults = await getModeledMethodsFromFlow (
123+ "source" ,
124+ "CaptureSourceModels.ql" ,
125+ 2 ,
126+ options ,
148127 ) ;
128+ if ( sourceResults ) {
129+ await onResults ( sourceResults ) ;
130+ }
149131
150- return generator . run ( onResults ) ;
132+ const neutralResults = await getModeledMethodsFromFlow (
133+ "neutral" ,
134+ "CaptureNeutralModels.ql" ,
135+ 3 ,
136+ options ,
137+ ) ;
138+ if ( neutralResults ) {
139+ await onResults ( neutralResults ) ;
140+ }
151141}
0 commit comments