Skip to content

Commit b3c5afb

Browse files
authored
Merge pull request #3052 from github/koesie10/argument-self
Extract creation of method argument options to languages
2 parents 146732f + b348356 commit b3c5afb

File tree

9 files changed

+104
-43
lines changed

9 files changed

+104
-43
lines changed

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MethodDefinition } from "../method";
1+
import { MethodArgument, MethodDefinition } from "../method";
22
import {
33
ModeledMethod,
44
NeutralModeledMethod,
@@ -45,6 +45,11 @@ export type ModelsAsDataLanguagePredicates = {
4545
neutral?: ModelsAsDataLanguagePredicate<NeutralModeledMethod>;
4646
};
4747

48+
export type MethodArgumentOptions = {
49+
options: MethodArgument[];
50+
defaultArgumentPath: string;
51+
};
52+
4853
export type ModelsAsDataLanguage = {
4954
/**
5055
* The modes that are available for this language. If not specified, all
@@ -54,4 +59,9 @@ export type ModelsAsDataLanguage = {
5459
createMethodSignature: (method: MethodDefinition) => string;
5560
predicates: ModelsAsDataLanguagePredicates;
5661
modelGeneration?: ModelsAsDataLanguageModelGeneration;
62+
/**
63+
* Returns the list of valid arguments that can be selected for the given method.
64+
* @param method The method to get the valid arguments for.
65+
*/
66+
getArgumentOptions: (method: MethodDefinition) => MethodArgumentOptions;
5767
};

extensions/ql-vscode/src/model-editor/languages/ruby/index.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ModelsAsDataLanguage } from "../models-as-data";
22
import { sharedExtensiblePredicates, sharedKinds } from "../shared";
33
import { Mode } from "../../shared/mode";
44
import { parseGenerateModelResults } from "./generate";
5+
import { getArgumentsList, MethodArgument } from "../../method";
56

67
function parseRubyMethodFromPath(path: string): string {
78
const match = path.match(/Method\[([^\]]+)].*/);
@@ -157,4 +158,25 @@ export const ruby: ModelsAsDataLanguage = {
157158
},
158159
parseResults: parseGenerateModelResults,
159160
},
161+
getArgumentOptions: (method) => {
162+
const argumentsList = getArgumentsList(method.methodParameters).map(
163+
(argument, index): MethodArgument => ({
164+
path: `Argument[${index}]`,
165+
label: `Argument[${index}]: ${argument}`,
166+
}),
167+
);
168+
169+
return {
170+
options: [
171+
{
172+
path: "Argument[self]",
173+
label: "Argument[self]",
174+
},
175+
...argumentsList,
176+
],
177+
// If there are no arguments, we will default to "Argument[self]"
178+
defaultArgumentPath:
179+
argumentsList.length > 0 ? argumentsList[0].path : "Argument[self]",
180+
};
181+
},
160182
};

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Provenance } from "../../modeled-method";
33
import { DataTuple } from "../../model-extension-file";
44
import { sharedExtensiblePredicates, sharedKinds } from "../shared";
55
import { filterFlowModelQueries, parseFlowModelResults } from "./generate";
6+
import { getArgumentsList, MethodArgument } from "../../method";
67

78
function readRowToMethod(row: DataTuple[]): string {
89
return `${row[0]}.${row[1]}#${row[3]}${row[4]}`;
@@ -145,4 +146,25 @@ export const staticLanguage: ModelsAsDataLanguage = {
145146
filterQueries: filterFlowModelQueries,
146147
parseResults: parseFlowModelResults,
147148
},
149+
getArgumentOptions: (method) => {
150+
const argumentsList = getArgumentsList(method.methodParameters).map(
151+
(argument, index): MethodArgument => ({
152+
path: `Argument[${index}]`,
153+
label: `Argument[${index}]: ${argument}`,
154+
}),
155+
);
156+
157+
return {
158+
options: [
159+
{
160+
path: "Argument[this]",
161+
label: "Argument[this]",
162+
},
163+
...argumentsList,
164+
],
165+
// If there are no arguments, we will default to "Argument[this]"
166+
defaultArgumentPath:
167+
argumentsList.length > 0 ? argumentsList[0].path : "Argument[this]",
168+
};
169+
},
148170
};

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ export interface Method extends MethodSignature {
6161
readonly usages: readonly Usage[];
6262
}
6363

64+
export interface MethodArgument {
65+
path: string;
66+
label: string;
67+
}
68+
6469
export function getArgumentsList(methodParameters: string): string[] {
6570
if (methodParameters === "()") {
6671
return [];

extensions/ql-vscode/src/view/method-modeling/MethodModelingInputs.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const MethodModelingInputs = ({
3939
onChange,
4040
}: MethodModelingInputsProps): JSX.Element => {
4141
const inputProps = {
42+
language,
4243
method,
4344
modeledMethod,
4445
onChange,
@@ -82,7 +83,7 @@ export const MethodModelingInputs = ({
8283
{isModelingInProgress ? (
8384
<InProgressDropdown />
8485
) : (
85-
<ModelKindDropdown language={language} {...inputProps} />
86+
<ModelKindDropdown {...inputProps} />
8687
)}
8788
</Input>
8889
</Container>

extensions/ql-vscode/src/view/model-editor/MethodRow.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,20 +234,23 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
234234
<DataGridRow key={index} focused={focusedIndex === index}>
235235
<DataGridCell>
236236
<ModelTypeDropdown
237+
language={viewState.language}
237238
method={method}
238239
modeledMethod={modeledMethod}
239240
onChange={modeledMethodChangedHandlers[index]}
240241
/>
241242
</DataGridCell>
242243
<DataGridCell>
243244
<ModelInputDropdown
245+
language={viewState.language}
244246
method={method}
245247
modeledMethod={modeledMethod}
246248
onChange={modeledMethodChangedHandlers[index]}
247249
/>
248250
</DataGridCell>
249251
<DataGridCell>
250252
<ModelOutputDropdown
253+
language={viewState.language}
251254
method={method}
252255
modeledMethod={modeledMethod}
253256
onChange={modeledMethodChangedHandlers[index]}

extensions/ql-vscode/src/view/model-editor/ModelInputDropdown.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,33 @@ import {
55
ModeledMethod,
66
modeledMethodSupportsInput,
77
} from "../../model-editor/modeled-method";
8-
import { Method, getArgumentsList } from "../../model-editor/method";
8+
import { Method } from "../../model-editor/method";
9+
import { QueryLanguage } from "../../common/query-language";
10+
import { getModelsAsDataLanguage } from "../../model-editor/languages";
911

1012
type Props = {
13+
language: QueryLanguage;
1114
method: Method;
1215
modeledMethod: ModeledMethod | undefined;
1316
onChange: (modeledMethod: ModeledMethod) => void;
1417
};
1518

1619
export const ModelInputDropdown = ({
20+
language,
1721
method,
1822
modeledMethod,
1923
onChange,
2024
}: Props): JSX.Element => {
21-
const argumentsList = useMemo(
22-
() => getArgumentsList(method.methodParameters),
23-
[method.methodParameters],
24-
);
25+
const options = useMemo(() => {
26+
const modelsAsDataLanguage = getModelsAsDataLanguage(language);
2527

26-
const options = useMemo(
27-
() => [
28-
{ value: "Argument[this]", label: "Argument[this]" },
29-
...argumentsList.map((argument, index) => ({
30-
value: `Argument[${index}]`,
31-
label: `Argument[${index}]: ${argument}`,
32-
})),
33-
],
34-
[argumentsList],
35-
);
28+
return modelsAsDataLanguage
29+
.getArgumentOptions(method)
30+
.options.map((option) => ({
31+
value: option.path,
32+
label: option.label,
33+
}));
34+
}, [language, method]);
3635

3736
const enabled = useMemo(
3837
() => modeledMethod && modeledMethodSupportsInput(modeledMethod),

extensions/ql-vscode/src/view/model-editor/ModelOutputDropdown.tsx

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,34 @@ import {
55
ModeledMethod,
66
modeledMethodSupportsOutput,
77
} from "../../model-editor/modeled-method";
8-
import { Method, getArgumentsList } from "../../model-editor/method";
8+
import { Method } from "../../model-editor/method";
9+
import { getModelsAsDataLanguage } from "../../model-editor/languages";
10+
import { QueryLanguage } from "../../common/query-language";
911

1012
type Props = {
13+
language: QueryLanguage;
1114
method: Method;
1215
modeledMethod: ModeledMethod | undefined;
1316
onChange: (modeledMethod: ModeledMethod) => void;
1417
};
1518

1619
export const ModelOutputDropdown = ({
20+
language,
1721
method,
1822
modeledMethod,
1923
onChange,
2024
}: Props): JSX.Element => {
21-
const argumentsList = useMemo(
22-
() => getArgumentsList(method.methodParameters),
23-
[method.methodParameters],
24-
);
25+
const options = useMemo(() => {
26+
const modelsAsDataLanguage = getModelsAsDataLanguage(language);
2527

26-
const options = useMemo(
27-
() => [
28-
{ value: "ReturnValue", label: "ReturnValue" },
29-
{ value: "Argument[this]", label: "Argument[this]" },
30-
...argumentsList.map((argument, index) => ({
31-
value: `Argument[${index}]`,
32-
label: `Argument[${index}]: ${argument}`,
33-
})),
34-
],
35-
[argumentsList],
36-
);
28+
const options = modelsAsDataLanguage
29+
.getArgumentOptions(method)
30+
.options.map((option) => ({
31+
value: option.path,
32+
label: option.label,
33+
}));
34+
return [{ value: "ReturnValue", label: "ReturnValue" }, ...options];
35+
}, [language, method]);
3736

3837
const enabled = useMemo(
3938
() => modeledMethod && modeledMethodSupportsOutput(modeledMethod),

extensions/ql-vscode/src/view/model-editor/ModelTypeDropdown.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import * as React from "react";
2-
import { ChangeEvent, useCallback, useMemo } from "react";
2+
import { ChangeEvent, useCallback } from "react";
33
import { Dropdown } from "../common/Dropdown";
44
import {
55
ModeledMethod,
66
modeledMethodSupportsProvenance,
77
ModeledMethodType,
88
Provenance,
99
} from "../../model-editor/modeled-method";
10-
import { Method, getArgumentsList } from "../../model-editor/method";
10+
import { Method } from "../../model-editor/method";
1111
import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empty";
1212
import { Mutable } from "../../common/mutable";
13+
import { QueryLanguage } from "../../common/query-language";
14+
import { getModelsAsDataLanguage } from "../../model-editor/languages";
1315

1416
const options: Array<{ value: ModeledMethodType; label: string }> = [
1517
{ value: "none", label: "Unmodeled" },
@@ -20,23 +22,22 @@ const options: Array<{ value: ModeledMethodType; label: string }> = [
2022
];
2123

2224
type Props = {
25+
language: QueryLanguage;
2326
method: Method;
2427
modeledMethod: ModeledMethod | undefined;
2528
onChange: (modeledMethod: ModeledMethod) => void;
2629
};
2730

2831
export const ModelTypeDropdown = ({
32+
language,
2933
method,
3034
modeledMethod,
3135
onChange,
3236
}: Props): JSX.Element => {
33-
const argumentsList = useMemo(
34-
() => getArgumentsList(method.methodParameters),
35-
[method.methodParameters],
36-
);
37-
3837
const handleChange = useCallback(
3938
(e: ChangeEvent<HTMLSelectElement>) => {
39+
const modelsAsDataLanguage = getModelsAsDataLanguage(language);
40+
4041
let newProvenance: Provenance = "manual";
4142
if (modeledMethod && modeledMethodSupportsProvenance(modeledMethod)) {
4243
if (modeledMethod.provenance === "df-generated") {
@@ -54,9 +55,8 @@ export const ModelTypeDropdown = ({
5455
...emptyModeledMethod,
5556
};
5657
if ("input" in updatedModeledMethod) {
57-
// If there are no arguments, we will default to "Argument[this]"
5858
updatedModeledMethod.input =
59-
argumentsList.length === 0 ? "Argument[this]" : "Argument[0]";
59+
modelsAsDataLanguage.getArgumentOptions(method).defaultArgumentPath;
6060
}
6161
if ("output" in updatedModeledMethod) {
6262
updatedModeledMethod.output = "ReturnValue";
@@ -70,7 +70,7 @@ export const ModelTypeDropdown = ({
7070

7171
onChange(updatedModeledMethod);
7272
},
73-
[onChange, method, modeledMethod, argumentsList],
73+
[onChange, method, modeledMethod, language],
7474
);
7575

7676
return (

0 commit comments

Comments
 (0)