Add experimental model editor support for Ruby

Make the minimum changes necessary for prototype Ruby support in the
model editor.

This consists of:

- Reading/writing modelled methods from/to data extensions in the
  dynamic languages format
- Special-casing Ruby in a few places where Java/C# was previously
  assumed.
This commit is contained in:
Harry Maclean
2023-10-18 13:39:26 +01:00
committed by Koen Vlaswinkel
parent f4a2d8572c
commit 9c5a963495
3 changed files with 154 additions and 1 deletions

View File

@@ -1,10 +1,12 @@
import { QueryLanguage } from "../../common/query-language";
import { ModelsAsDataLanguage } from "./models-as-data";
import { ruby } from "./ruby";
import { staticLanguage } from "./static";
const languages: Partial<Record<QueryLanguage, ModelsAsDataLanguage>> = {
[QueryLanguage.CSharp]: staticLanguage,
[QueryLanguage.Java]: staticLanguage,
[QueryLanguage.Ruby]: ruby,
};
export function getModelsAsDataLanguage(

View File

@@ -0,0 +1,151 @@
import { ModelsAsDataLanguage } from "./models-as-data";
import { sharedExtensiblePredicates, sharedKinds } from "./shared";
function parseRubyMethodFromPath(path: string): string {
const match = path.match(/Method\[([^\]]+)].*/);
if (match) {
return match[1];
} else {
return "";
}
}
function parseRubyAccessPath(path: string): {
methodName: string;
path: string;
} {
const match = path.match(/Method\[([^\]]+)]\.(.*)/);
if (match) {
return { methodName: match[1], path: match[2] };
} else {
return { methodName: "", path: "" };
}
}
function rubyMethodSignature(typeName: string, methodName: string) {
return `${typeName}#${methodName}`;
}
export const ruby: ModelsAsDataLanguage = {
createMethodSignature: ({ typeName, methodName }) =>
`${typeName}#${methodName}`,
predicates: {
source: {
extensiblePredicate: sharedExtensiblePredicates.source,
supportedKinds: sharedKinds.source,
// extensible predicate sourceModel(
// string type, string path, string kind
// );
generateMethodDefinition: (method) => [
method.typeName,
`Method[${method.methodName}].${method.output}`,
method.kind,
],
readModeledMethod: (row) => {
const typeName = row[0] as string;
const { methodName, path: output } = parseRubyAccessPath(
row[1] as string,
);
return {
type: "source",
input: "",
output,
kind: row[2] as string,
provenance: "manual",
signature: rubyMethodSignature(typeName, methodName),
packageName: "",
typeName,
methodName,
methodParameters: "",
};
},
},
sink: {
extensiblePredicate: sharedExtensiblePredicates.sink,
supportedKinds: sharedKinds.sink,
// extensible predicate sinkModel(
// string type, string path, string kind
// );
generateMethodDefinition: (method) => {
const path = `Method[${method.methodName}].${method.input}`;
return [method.typeName, path, method.kind];
},
readModeledMethod: (row) => {
const typeName = row[0] as string;
const { methodName, path: input } = parseRubyAccessPath(
row[1] as string,
);
return {
type: "sink",
input,
output: "",
kind: row[2] as string,
provenance: "manual",
signature: rubyMethodSignature(typeName, methodName),
packageName: "",
typeName,
methodName,
methodParameters: "",
};
},
},
summary: {
extensiblePredicate: sharedExtensiblePredicates.summary,
supportedKinds: sharedKinds.summary,
// extensible predicate summaryModel(
// string type, string path, string input, string output, string kind
// );
generateMethodDefinition: (method) => [
method.typeName,
`Method[${method.methodName}]`,
method.input,
method.output,
method.kind,
],
readModeledMethod: (row) => {
const typeName = row[0] as string;
const methodName = parseRubyMethodFromPath(row[1] as string);
return {
type: "summary",
input: row[2] as string,
output: row[3] as string,
kind: row[4] as string,
provenance: "manual",
signature: rubyMethodSignature(typeName, methodName),
packageName: "",
typeName,
methodName,
methodParameters: "",
};
},
},
neutral: {
extensiblePredicate: sharedExtensiblePredicates.neutral,
supportedKinds: sharedKinds.neutral,
// extensible predicate neutralModel(
// string type, string path, string kind
// );
generateMethodDefinition: (method) => [
method.typeName,
`Method[${method.methodName}]`,
method.kind,
],
readModeledMethod: (row) => {
const typeName = row[0] as string;
const methodName = parseRubyMethodFromPath(row[1] as string);
return {
type: "neutral",
input: "",
output: "",
kind: row[2] as string,
provenance: "manual",
signature: rubyMethodSignature(typeName, methodName),
packageName: "",
typeName,
methodName,
methodParameters: "",
};
},
},
},
};

View File

@@ -23,7 +23,7 @@ import { ModelEditorViewTracker } from "./model-editor-view-tracker";
import { ModelConfigListener } from "../config";
import { ModelingEvents } from "./modeling-events";
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp", "ruby"];
export class ModelEditorModule extends DisposableObject {
private readonly queryStorageDir: string;