Skip to content

Commit ecb2503

Browse files
committed
Use MaD definition when decoding BQRS
This will use the MaD's definition of a method signature when decoding BQRS files. This will allow us to change the method signature definition for dynamic languages.
1 parent b9fa79a commit ecb2503

File tree

8 files changed

+54
-19
lines changed

8 files changed

+54
-19
lines changed

extensions/ql-vscode/src/model-editor/bqrs.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ import { ModeledMethodType } from "./modeled-method";
44
import { parseLibraryFilename } from "./library";
55
import { Mode } from "./shared/mode";
66
import { ApplicationModeTuple, FrameworkModeTuple } from "./queries/query";
7+
import { QueryLanguage } from "../common/query-language";
8+
import { getModelsAsDataLanguage } from "./languages";
79

810
export function decodeBqrsToMethods(
911
chunk: DecodedBqrsChunk,
1012
mode: Mode,
13+
language: QueryLanguage,
1114
): Method[] {
1215
const methodsByApiName = new Map<string, Method>();
1316

17+
const definition = getModelsAsDataLanguage(language);
18+
1419
chunk?.tuples.forEach((tuple) => {
1520
let usage: Call;
1621
let packageName: string;
@@ -51,7 +56,12 @@ export function decodeBqrsToMethods(
5156
classification = CallClassification.Unknown;
5257
}
5358

54-
const signature = `${packageName}.${typeName}#${methodName}${methodParameters}`;
59+
const signature = definition.createMethodSignature({
60+
packageName,
61+
typeName,
62+
methodName,
63+
methodParameters,
64+
});
5565

5666
// For Java, we'll always get back a .jar file, and the library version may be bad because not all library authors
5767
// properly specify the version. Therefore, we'll always try to parse the name and version from the library filename

extensions/ql-vscode/src/model-editor/languages/models-as-data.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { MethodDefinition } from "../method";
12
import { ModeledMethod, ModeledMethodType } from "../modeled-method";
23
import { DataTuple } from "../model-extension-file";
34

@@ -19,5 +20,6 @@ export type ModelsAsDataLanguagePredicates = Record<
1920
>;
2021

2122
export type ModelsAsDataLanguage = {
23+
createMethodSignature: (method: MethodDefinition) => string;
2224
predicates: ModelsAsDataLanguagePredicates;
2325
};

extensions/ql-vscode/src/model-editor/languages/static.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ function readRowToMethod(row: DataTuple[]): string {
88
}
99

1010
export const staticLanguage: ModelsAsDataLanguage = {
11+
createMethodSignature: ({
12+
packageName,
13+
typeName,
14+
methodName,
15+
methodParameters,
16+
}) => `${packageName}.${typeName}#${methodName}${methodParameters}`,
1117
predicates: {
1218
source: {
1319
extensiblePredicate: sharedExtensiblePredicates.source,

extensions/ql-vscode/src/model-editor/method.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,7 @@ export type Usage = Call & {
1717
readonly classification: CallClassification;
1818
};
1919

20-
export interface MethodSignature {
21-
/**
22-
* Contains the version of the library if it can be determined by CodeQL, e.g. `4.2.2.2`
23-
*/
24-
readonly libraryVersion?: string;
25-
/**
26-
* A unique signature that can be used to identify this external API usage.
27-
*
28-
* The signature contains the package name, type name, method name, and method parameters
29-
* in the form "packageName.typeName#methodName(methodParameters)".
30-
* e.g. `org.sql2o.Connection#createQuery(String)`
31-
*/
32-
readonly signature: string;
20+
export interface MethodDefinition {
3321
/**
3422
* The package name in Java, or the namespace in C#, e.g. `org.sql2o` or `System.Net.Http.Headers`.
3523
*
@@ -44,6 +32,21 @@ export interface MethodSignature {
4432
readonly methodParameters: string;
4533
}
4634

35+
export interface MethodSignature extends MethodDefinition {
36+
/**
37+
* Contains the version of the library if it can be determined by CodeQL, e.g. `4.2.2.2`
38+
*/
39+
readonly libraryVersion?: string;
40+
/**
41+
* A unique signature that can be used to identify this external API usage.
42+
*
43+
* The signature contains the package name, type name, method name, and method parameters
44+
* in the form "packageName.typeName#methodName(methodParameters)".
45+
* e.g. `org.sql2o.Connection#createQuery(String)`
46+
*/
47+
readonly signature: string;
48+
}
49+
4750
export interface Method extends MethodSignature {
4851
/**
4952
* Contains the name of the library containing the method declaration, e.g. `sql2o-1.6.0.jar` or `System.Runtime.dll`

extensions/ql-vscode/src/model-editor/model-editor-queries.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type RunQueryOptions = {
2525
cliServer: CodeQLCliServer;
2626
queryRunner: QueryRunner;
2727
databaseItem: DatabaseItem;
28+
language: QueryLanguage;
2829
queryStorageDir: string;
2930
queryDir: string;
3031

@@ -70,6 +71,7 @@ export async function runModelEditorQueries(
7071
cliServer,
7172
queryRunner,
7273
databaseItem,
74+
language,
7375
queryStorageDir,
7476
queryDir,
7577
progress,
@@ -157,7 +159,7 @@ export async function runModelEditorQueries(
157159
maxStep: externalApiQueriesProgressMaxStep,
158160
});
159161

160-
return decodeBqrsToMethods(bqrsChunk, mode);
162+
return decodeBqrsToMethods(bqrsChunk, mode, language);
161163
}
162164

163165
type GetResultsOptions = {

extensions/ql-vscode/src/model-editor/model-editor-view.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ export class ModelEditorView extends AbstractWebview<
430430
cliServer: this.cliServer,
431431
queryRunner: this.queryRunner,
432432
databaseItem: this.databaseItem,
433+
language: this.language,
433434
queryStorageDir: this.queryStorageDir,
434435
queryDir: this.queryDir,
435436
progress: (update) =>

extensions/ql-vscode/test/unit-tests/model-editor/bqrs.test.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { decodeBqrsToMethods } from "../../../src/model-editor/bqrs";
22
import { DecodedBqrsChunk } from "../../../src/common/bqrs-cli-types";
33
import { CallClassification } from "../../../src/model-editor/method";
44
import { Mode } from "../../../src/model-editor/shared/mode";
5+
import { QueryLanguage } from "../../../src/common/query-language";
56

67
describe("decodeBqrsToMethods", () => {
78
describe("Java queries", () => {
@@ -237,7 +238,9 @@ describe("decodeBqrsToMethods", () => {
237238
// Even though there are a number of methods with the same number of usages, the order returned should be stable:
238239
// - Iterating over a map (as done by .values()) is guaranteed to be in insertion order
239240
// - Sorting the array of methods is guaranteed to be a stable sort
240-
expect(decodeBqrsToMethods(chunk, Mode.Application)).toEqual([
241+
expect(
242+
decodeBqrsToMethods(chunk, Mode.Application, QueryLanguage.Java),
243+
).toEqual([
241244
{
242245
library: "rt",
243246
libraryVersion: undefined,
@@ -499,7 +502,9 @@ describe("decodeBqrsToMethods", () => {
499502
};
500503

501504
it("extracts methods", () => {
502-
expect(decodeBqrsToMethods(chunk, Mode.Framework)).toEqual([
505+
expect(
506+
decodeBqrsToMethods(chunk, Mode.Framework, QueryLanguage.Java),
507+
).toEqual([
503508
{
504509
library: "",
505510
libraryVersion: undefined,
@@ -594,7 +599,9 @@ describe("decodeBqrsToMethods", () => {
594599
};
595600

596601
it("extracts methods", () => {
597-
expect(decodeBqrsToMethods(chunk, Mode.Application)).toEqual([
602+
expect(
603+
decodeBqrsToMethods(chunk, Mode.Application, QueryLanguage.Java),
604+
).toEqual([
598605
{
599606
library: "mscorlib",
600607
libraryVersion: "4.0.0.0",
@@ -660,7 +667,9 @@ describe("decodeBqrsToMethods", () => {
660667
};
661668

662669
it("extracts methods", () => {
663-
expect(decodeBqrsToMethods(chunk, Mode.Framework)).toEqual([
670+
expect(
671+
decodeBqrsToMethods(chunk, Mode.Framework, QueryLanguage.Java),
672+
).toEqual([
664673
{
665674
library: "Times",
666675
libraryVersion: undefined,

extensions/ql-vscode/test/vscode-tests/no-workspace/model-editor/external-api-usage-query.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ describe("runModelEditorQueries", () => {
7474
},
7575
language,
7676
}),
77+
language,
7778
queryStorageDir: "/tmp/queries",
7879
queryDir,
7980
progress: jest.fn(),
@@ -139,6 +140,7 @@ describe("runModelEditorQueries", () => {
139140
},
140141
language,
141142
}),
143+
language,
142144
queryStorageDir: "/tmp/queries",
143145
queryDir,
144146
progress: jest.fn(),

0 commit comments

Comments
 (0)