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:
committed by
Koen Vlaswinkel
parent
f4a2d8572c
commit
9c5a963495
@@ -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(
|
||||
|
||||
151
extensions/ql-vscode/src/model-editor/languages/ruby.ts
Normal file
151
extensions/ql-vscode/src/model-editor/languages/ruby.ts
Normal 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: "",
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user