Merge remote-tracking branch 'origin/main' into koesie10/update-set-selected-method-message

This commit is contained in:
Koen Vlaswinkel
2023-10-11 13:40:27 +02:00
13 changed files with 194 additions and 199 deletions

View File

@@ -507,7 +507,7 @@ interface SetMethodsMessage {
interface SetModeledMethodsMessage { interface SetModeledMethodsMessage {
t: "setModeledMethods"; t: "setModeledMethods";
methods: Record<string, ModeledMethod>; methods: Record<string, ModeledMethod[]>;
} }
interface SetModifiedMethodsMessage { interface SetModifiedMethodsMessage {

View File

@@ -102,7 +102,7 @@ export class MethodsUsageDataProvider
} }
private getModelingStatusIcon(method: Method): ThemeIcon { private getModelingStatusIcon(method: Method): ThemeIcon {
const modeledMethods = this.modeledMethods[method.signature]; const modeledMethods = this.modeledMethods[method.signature] ?? [];
const modifiedMethod = this.modifiedMethodSignatures.has(method.signature); const modifiedMethod = this.modifiedMethodSignatures.has(method.signature);
const status = getModelingStatus(modeledMethods, modifiedMethod); const status = getModelingStatus(modeledMethods, modifiedMethod);

View File

@@ -43,10 +43,7 @@ import { AutoModeler } from "./auto-modeler";
import { telemetryListener } from "../common/vscode/telemetry"; import { telemetryListener } from "../common/vscode/telemetry";
import { ModelingStore } from "./modeling-store"; import { ModelingStore } from "./modeling-store";
import { ModelEditorViewTracker } from "./model-editor-view-tracker"; import { ModelEditorViewTracker } from "./model-editor-view-tracker";
import { import { convertFromLegacyModeledMethod } from "./shared/modeled-methods-legacy";
convertFromLegacyModeledMethod,
convertToLegacyModeledMethods,
} from "./shared/modeled-methods-legacy";
export class ModelEditorView extends AbstractWebview< export class ModelEditorView extends AbstractWebview<
ToModelEditorMessage, ToModelEditorMessage,
@@ -640,7 +637,7 @@ export class ModelEditorView extends AbstractWebview<
if (event.dbUri === this.databaseItem.databaseUri.toString()) { if (event.dbUri === this.databaseItem.databaseUri.toString()) {
await this.postMessage({ await this.postMessage({
t: "setModeledMethods", t: "setModeledMethods",
methods: convertToLegacyModeledMethods(event.modeledMethods), methods: event.modeledMethods,
}); });
} }
}), }),

View File

@@ -1,32 +1,5 @@
import { ModeledMethod } from "../modeled-method"; import { ModeledMethod } from "../modeled-method";
/**
* Converts a record of a single ModeledMethod indexed by signature to a record of ModeledMethod[] indexed by signature
* for legacy usage. This function should always be used instead of the trivial conversion to track usages of this
* conversion.
*
* This method should only be called inside a `postMessage` call. If it's used anywhere else, consider whether the
* boundary is correct: the boundary should as close as possible to the extension host -> webview boundary.
*
* @param modeledMethods The record of a single ModeledMethod indexed by signature
*/
export function convertToLegacyModeledMethods(
modeledMethods: Record<string, ModeledMethod[]>,
): Record<string, ModeledMethod> {
// Always take the first modeled method in the array
return Object.fromEntries(
Object.entries(modeledMethods)
.map(([signature, modeledMethods]) => {
const modeledMethod = convertToLegacyModeledMethod(modeledMethods);
if (!modeledMethod) {
return null;
}
return [signature, modeledMethod];
})
.filter((entry): entry is [string, ModeledMethod] => entry !== null),
);
}
/** /**
* Converts a single ModeledMethod to a ModeledMethod[] for legacy usage. This function should always be used instead * Converts a single ModeledMethod to a ModeledMethod[] for legacy usage. This function should always be used instead
* of the trivial conversion to track usages of this conversion. * of the trivial conversion to track usages of this conversion.

View File

@@ -146,67 +146,77 @@ LibraryRow.args = {
], ],
}, },
], ],
modeledMethods: { modeledMethodsMap: {
"org.sql2o.Sql2o#Sql2o(String)": { "org.sql2o.Sql2o#Sql2o(String)": [
type: "sink", {
input: "Argument[0]", type: "sink",
output: "", input: "Argument[0]",
kind: "jndi-injection", output: "",
provenance: "df-generated", kind: "jndi-injection",
signature: "org.sql2o.Sql2o#Sql2o(String)", provenance: "df-generated",
packageName: "org.sql2o", signature: "org.sql2o.Sql2o#Sql2o(String)",
typeName: "Sql2o", packageName: "org.sql2o",
methodName: "Sql2o", typeName: "Sql2o",
methodParameters: "(String)", methodName: "Sql2o",
}, methodParameters: "(String)",
"org.sql2o.Connection#createQuery(String)": { },
type: "summary", ],
input: "Argument[this]", "org.sql2o.Connection#createQuery(String)": [
output: "ReturnValue", {
kind: "taint", type: "summary",
provenance: "df-manual", input: "Argument[this]",
signature: "org.sql2o.Connection#createQuery(String)", output: "ReturnValue",
packageName: "org.sql2o", kind: "taint",
typeName: "Connection", provenance: "df-manual",
methodName: "createQuery", signature: "org.sql2o.Connection#createQuery(String)",
methodParameters: "(String)", packageName: "org.sql2o",
}, typeName: "Connection",
"org.sql2o.Sql2o#open()": { methodName: "createQuery",
type: "summary", methodParameters: "(String)",
input: "Argument[this]", },
output: "ReturnValue", ],
kind: "taint", "org.sql2o.Sql2o#open()": [
provenance: "manual", {
signature: "org.sql2o.Sql2o#open()", type: "summary",
packageName: "org.sql2o", input: "Argument[this]",
typeName: "Sql2o", output: "ReturnValue",
methodName: "open", kind: "taint",
methodParameters: "()", provenance: "manual",
}, signature: "org.sql2o.Sql2o#open()",
"org.sql2o.Query#executeScalar(Class)": { packageName: "org.sql2o",
type: "neutral", typeName: "Sql2o",
input: "", methodName: "open",
output: "", methodParameters: "()",
kind: "", },
provenance: "df-generated", ],
signature: "org.sql2o.Query#executeScalar(Class)", "org.sql2o.Query#executeScalar(Class)": [
packageName: "org.sql2o", {
typeName: "Query", type: "neutral",
methodName: "executeScalar", input: "",
methodParameters: "(Class)", output: "",
}, kind: "",
"org.sql2o.Sql2o#Sql2o(String,String,String)": { provenance: "df-generated",
type: "neutral", signature: "org.sql2o.Query#executeScalar(Class)",
input: "", packageName: "org.sql2o",
output: "", typeName: "Query",
kind: "", methodName: "executeScalar",
provenance: "df-generated", methodParameters: "(Class)",
signature: "org.sql2o.Sql2o#Sql2o(String,String,String)", },
packageName: "org.sql2o", ],
typeName: "Sql2o", "org.sql2o.Sql2o#Sql2o(String,String,String)": [
methodName: "Sql2o", {
methodParameters: "(String,String,String)", type: "neutral",
}, input: "",
output: "",
kind: "",
provenance: "df-generated",
signature: "org.sql2o.Sql2o#Sql2o(String,String,String)",
packageName: "org.sql2o",
typeName: "Sql2o",
methodName: "Sql2o",
methodParameters: "(String,String,String)",
},
],
}, },
modifiedSignatures: new Set(["org.sql2o.Sql2o#Sql2o(String)"]), modifiedSignatures: new Set(["org.sql2o.Sql2o#Sql2o(String)"]),
inProgressMethods: new InProgressMethods(), inProgressMethods: new InProgressMethods(),

View File

@@ -216,65 +216,75 @@ ModelEditor.args = {
}, },
], ],
initialModeledMethods: { initialModeledMethods: {
"org.sql2o.Sql2o#Sql2o(String)": { "org.sql2o.Sql2o#Sql2o(String)": [
type: "sink", {
input: "Argument[0]", type: "sink",
output: "", input: "Argument[0]",
kind: "jndi-injection", output: "",
provenance: "df-generated", kind: "jndi-injection",
signature: "org.sql2o.Sql2o#Sql2o(String)", provenance: "df-generated",
packageName: "org.sql2o", signature: "org.sql2o.Sql2o#Sql2o(String)",
typeName: "Sql2o", packageName: "org.sql2o",
methodName: "Sql2o", typeName: "Sql2o",
methodParameters: "(String)", methodName: "Sql2o",
}, methodParameters: "(String)",
"org.sql2o.Connection#createQuery(String)": { },
type: "summary", ],
input: "Argument[this]", "org.sql2o.Connection#createQuery(String)": [
output: "ReturnValue", {
kind: "taint", type: "summary",
provenance: "df-manual", input: "Argument[this]",
signature: "org.sql2o.Connection#createQuery(String)", output: "ReturnValue",
packageName: "org.sql2o", kind: "taint",
typeName: "Connection", provenance: "df-manual",
methodName: "createQuery", signature: "org.sql2o.Connection#createQuery(String)",
methodParameters: "(String)", packageName: "org.sql2o",
}, typeName: "Connection",
"org.sql2o.Sql2o#open()": { methodName: "createQuery",
type: "summary", methodParameters: "(String)",
input: "Argument[this]", },
output: "ReturnValue", ],
kind: "taint", "org.sql2o.Sql2o#open()": [
provenance: "manual", {
signature: "org.sql2o.Sql2o#open()", type: "summary",
packageName: "org.sql2o", input: "Argument[this]",
typeName: "Sql2o", output: "ReturnValue",
methodName: "open", kind: "taint",
methodParameters: "()", provenance: "manual",
}, signature: "org.sql2o.Sql2o#open()",
"org.sql2o.Query#executeScalar(Class)": { packageName: "org.sql2o",
type: "neutral", typeName: "Sql2o",
input: "", methodName: "open",
output: "", methodParameters: "()",
kind: "", },
provenance: "df-generated", ],
signature: "org.sql2o.Query#executeScalar(Class)", "org.sql2o.Query#executeScalar(Class)": [
packageName: "org.sql2o", {
typeName: "Query", type: "neutral",
methodName: "executeScalar", input: "",
methodParameters: "(Class)", output: "",
}, kind: "",
"org.sql2o.Sql2o#Sql2o(String,String,String)": { provenance: "df-generated",
type: "neutral", signature: "org.sql2o.Query#executeScalar(Class)",
input: "", packageName: "org.sql2o",
output: "", typeName: "Query",
kind: "", methodName: "executeScalar",
provenance: "df-generated", methodParameters: "(Class)",
signature: "org.sql2o.Sql2o#Sql2o(String,String,String)", },
packageName: "org.sql2o", ],
typeName: "Sql2o", "org.sql2o.Sql2o#Sql2o(String,String,String)": [
methodName: "Sql2o", {
methodParameters: "(String,String,String)", type: "neutral",
}, input: "",
output: "",
kind: "",
provenance: "df-generated",
signature: "org.sql2o.Sql2o#Sql2o(String,String,String)",
packageName: "org.sql2o",
typeName: "Sql2o",
methodName: "Sql2o",
methodParameters: "(String,String,String)",
},
],
}, },
}; };

View File

@@ -71,7 +71,7 @@ export type LibraryRowProps = {
title: string; title: string;
libraryVersion?: string; libraryVersion?: string;
methods: Method[]; methods: Method[];
modeledMethods: Record<string, ModeledMethod>; modeledMethodsMap: Record<string, ModeledMethod[]>;
modifiedSignatures: Set<string>; modifiedSignatures: Set<string>;
inProgressMethods: InProgressMethods; inProgressMethods: InProgressMethods;
viewState: ModelEditorViewState; viewState: ModelEditorViewState;
@@ -92,7 +92,7 @@ export const LibraryRow = ({
title, title,
libraryVersion, libraryVersion,
methods, methods,
modeledMethods, modeledMethodsMap,
modifiedSignatures, modifiedSignatures,
inProgressMethods, inProgressMethods,
viewState, viewState,
@@ -231,7 +231,7 @@ export const LibraryRow = ({
<ModeledMethodDataGrid <ModeledMethodDataGrid
packageName={title} packageName={title}
methods={methods} methods={methods}
modeledMethods={modeledMethods} modeledMethodsMap={modeledMethodsMap}
modifiedSignatures={modifiedSignatures} modifiedSignatures={modifiedSignatures}
inProgressMethods={inProgressMethods} inProgressMethods={inProgressMethods}
viewState={viewState} viewState={viewState}

View File

@@ -74,7 +74,7 @@ const ButtonsContainer = styled.div`
type Props = { type Props = {
initialViewState?: ModelEditorViewState; initialViewState?: ModelEditorViewState;
initialMethods?: Method[]; initialMethods?: Method[];
initialModeledMethods?: Record<string, ModeledMethod>; initialModeledMethods?: Record<string, ModeledMethod[]>;
initialHideModeledMethods?: boolean; initialHideModeledMethods?: boolean;
}; };
@@ -113,7 +113,7 @@ export function ModelEditor({
}, [hideModeledMethods]); }, [hideModeledMethods]);
const [modeledMethods, setModeledMethods] = useState< const [modeledMethods, setModeledMethods] = useState<
Record<string, ModeledMethod> Record<string, ModeledMethod[]>
>(initialModeledMethods); >(initialModeledMethods);
useEffect(() => { useEffect(() => {
@@ -329,7 +329,7 @@ export function ModelEditor({
</ButtonsContainer> </ButtonsContainer>
<ModeledMethodsList <ModeledMethodsList
methods={methods} methods={methods}
modeledMethods={modeledMethods} modeledMethodsMap={modeledMethods}
modifiedSignatures={modifiedSignatures} modifiedSignatures={modifiedSignatures}
inProgressMethods={inProgressMethods} inProgressMethods={inProgressMethods}
viewState={viewState} viewState={viewState}

View File

@@ -12,14 +12,13 @@ import { sortMethods } from "../../model-editor/shared/sorting";
import { InProgressMethods } from "../../model-editor/shared/in-progress-methods"; import { InProgressMethods } from "../../model-editor/shared/in-progress-methods";
import { HiddenMethodsRow } from "./HiddenMethodsRow"; import { HiddenMethodsRow } from "./HiddenMethodsRow";
import { ModelEditorViewState } from "../../model-editor/shared/view-state"; import { ModelEditorViewState } from "../../model-editor/shared/view-state";
import { convertFromLegacyModeledMethod } from "../../model-editor/shared/modeled-methods-legacy";
export const GRID_TEMPLATE_COLUMNS = "0.5fr 0.125fr 0.125fr 0.125fr 0.125fr"; export const GRID_TEMPLATE_COLUMNS = "0.5fr 0.125fr 0.125fr 0.125fr 0.125fr";
export type ModeledMethodDataGridProps = { export type ModeledMethodDataGridProps = {
packageName: string; packageName: string;
methods: Method[]; methods: Method[];
modeledMethods: Record<string, ModeledMethod>; modeledMethodsMap: Record<string, ModeledMethod[]>;
modifiedSignatures: Set<string>; modifiedSignatures: Set<string>;
inProgressMethods: InProgressMethods; inProgressMethods: InProgressMethods;
viewState: ModelEditorViewState; viewState: ModelEditorViewState;
@@ -31,7 +30,7 @@ export type ModeledMethodDataGridProps = {
export const ModeledMethodDataGrid = ({ export const ModeledMethodDataGrid = ({
packageName, packageName,
methods, methods,
modeledMethods, modeledMethodsMap,
modifiedSignatures, modifiedSignatures,
inProgressMethods, inProgressMethods,
viewState, viewState,
@@ -46,11 +45,11 @@ export const ModeledMethodDataGrid = ({
const methodsWithModelability = []; const methodsWithModelability = [];
let numHiddenMethods = 0; let numHiddenMethods = 0;
for (const method of sortMethods(methods)) { for (const method of sortMethods(methods)) {
const modeledMethod = modeledMethods[method.signature]; const modeledMethods = modeledMethodsMap[method.signature] ?? [];
const methodIsUnsaved = modifiedSignatures.has(method.signature); const methodIsUnsaved = modifiedSignatures.has(method.signature);
const methodCanBeModeled = canMethodBeModeled( const methodCanBeModeled = canMethodBeModeled(
method, method,
convertFromLegacyModeledMethod(modeledMethod), modeledMethods,
methodIsUnsaved, methodIsUnsaved,
); );
@@ -61,7 +60,7 @@ export const ModeledMethodDataGrid = ({
} }
} }
return [methodsWithModelability, numHiddenMethods]; return [methodsWithModelability, numHiddenMethods];
}, [hideModeledMethods, methods, modeledMethods, modifiedSignatures]); }, [hideModeledMethods, methods, modeledMethodsMap, modifiedSignatures]);
const someMethodsAreVisible = methodsWithModelability.length > 0; const someMethodsAreVisible = methodsWithModelability.length > 0;
@@ -87,13 +86,13 @@ export const ModeledMethodDataGrid = ({
</VSCodeDataGridCell> </VSCodeDataGridCell>
</VSCodeDataGridRow> </VSCodeDataGridRow>
{methodsWithModelability.map(({ method, methodCanBeModeled }) => { {methodsWithModelability.map(({ method, methodCanBeModeled }) => {
const modeledMethod = modeledMethods[method.signature]; const modeledMethods = modeledMethodsMap[method.signature] ?? [];
return ( return (
<MethodRow <MethodRow
key={method.signature} key={method.signature}
method={method} method={method}
methodCanBeModeled={methodCanBeModeled} methodCanBeModeled={methodCanBeModeled}
modeledMethods={modeledMethod ? [modeledMethod] : []} modeledMethods={modeledMethods}
methodIsUnsaved={modifiedSignatures.has(method.signature)} methodIsUnsaved={modifiedSignatures.has(method.signature)}
modelingInProgress={inProgressMethods.hasMethod( modelingInProgress={inProgressMethods.hasMethod(
packageName, packageName,

View File

@@ -13,7 +13,7 @@ import { InProgressMethods } from "../../model-editor/shared/in-progress-methods
export type ModeledMethodsListProps = { export type ModeledMethodsListProps = {
methods: Method[]; methods: Method[];
modeledMethods: Record<string, ModeledMethod>; modeledMethodsMap: Record<string, ModeledMethod[]>;
modifiedSignatures: Set<string>; modifiedSignatures: Set<string>;
inProgressMethods: InProgressMethods; inProgressMethods: InProgressMethods;
revealedMethodSignature: string | null; revealedMethodSignature: string | null;
@@ -36,7 +36,7 @@ const libraryNameOverrides: Record<string, string> = {
export const ModeledMethodsList = ({ export const ModeledMethodsList = ({
methods, methods,
modeledMethods, modeledMethodsMap,
modifiedSignatures, modifiedSignatures,
inProgressMethods, inProgressMethods,
viewState, viewState,
@@ -82,7 +82,7 @@ export const ModeledMethodsList = ({
title={libraryNameOverrides[libraryName] ?? libraryName} title={libraryNameOverrides[libraryName] ?? libraryName}
libraryVersion={libraryVersions[libraryName]} libraryVersion={libraryVersions[libraryName]}
methods={grouped[libraryName]} methods={grouped[libraryName]}
modeledMethods={modeledMethods} modeledMethodsMap={modeledMethodsMap}
modifiedSignatures={modifiedSignatures} modifiedSignatures={modifiedSignatures}
inProgressMethods={inProgressMethods} inProgressMethods={inProgressMethods}
viewState={viewState} viewState={viewState}

View File

@@ -30,15 +30,17 @@ describe(LibraryRow.name, () => {
title="sql2o" title="sql2o"
libraryVersion="1.6.0" libraryVersion="1.6.0"
methods={[method]} methods={[method]}
modeledMethods={{ modeledMethodsMap={{
[method.signature]: { [method.signature]: [
...method, {
type: "sink", ...method,
input: "Argument[0]", type: "sink",
output: "", input: "Argument[0]",
kind: "jndi-injection", output: "",
provenance: "df-generated", kind: "jndi-injection",
}, provenance: "df-generated",
},
],
}} }}
modifiedSignatures={new Set([method.signature])} modifiedSignatures={new Set([method.signature])}
inProgressMethods={new InProgressMethods()} inProgressMethods={new InProgressMethods()}

View File

@@ -56,15 +56,17 @@ describe(ModeledMethodDataGrid.name, () => {
<ModeledMethodDataGrid <ModeledMethodDataGrid
packageName="sql2o" packageName="sql2o"
methods={[method1, method2, method3]} methods={[method1, method2, method3]}
modeledMethods={{ modeledMethodsMap={{
[method1.signature]: { [method1.signature]: [
...method1, {
type: "sink", ...method1,
input: "Argument[0]", type: "sink",
output: "", input: "Argument[0]",
kind: "jndi-injection", output: "",
provenance: "df-generated", kind: "jndi-injection",
}, provenance: "df-generated",
},
],
}} }}
modifiedSignatures={new Set([method1.signature])} modifiedSignatures={new Set([method1.signature])}
inProgressMethods={new InProgressMethods()} inProgressMethods={new InProgressMethods()}

View File

@@ -56,15 +56,17 @@ describe(ModeledMethodsList.name, () => {
reactRender( reactRender(
<ModeledMethodsList <ModeledMethodsList
methods={[method1, method2, method3]} methods={[method1, method2, method3]}
modeledMethods={{ modeledMethodsMap={{
[method1.signature]: { [method1.signature]: [
...method1, {
type: "sink", ...method1,
input: "Argument[0]", type: "sink",
output: "", input: "Argument[0]",
kind: "jndi-injection", output: "",
provenance: "df-generated", kind: "jndi-injection",
}, provenance: "df-generated",
},
],
}} }}
modifiedSignatures={new Set([method1.signature])} modifiedSignatures={new Set([method1.signature])}
inProgressMethods={new InProgressMethods()} inProgressMethods={new InProgressMethods()}