Add auto-model generation mode without separate file

This commit is contained in:
Koen Vlaswinkel
2024-04-10 16:46:45 +02:00
parent 8a3a6d7e7e
commit fed30b6fed
3 changed files with 105 additions and 30 deletions

View File

@@ -105,15 +105,34 @@ type ParseResultsToYaml = (
logger: BaseLogger,
) => ModelExtension[];
export enum AutoModelGenerationType {
/**
* Auto model generation is disabled and will not be run.
*/
Disabled = "disabled",
/**
* The models are generated to a separate file (suffixed with .model.generated.yml).
*/
SeparateFile = "separateFile",
/**
* The models are added as a model in the model editor, but are not automatically saved.
* The user can view them and choose to save them.
*/
Models = "models",
}
type ModelsAsDataLanguageAutoModelGeneration = {
queryConstraints: (mode: Mode) => QueryConstraints;
filterQueries?: (queryPath: string) => boolean;
/**
* This function is only used when type is `separateFile`.
*/
parseResultsToYaml: ParseResultsToYaml;
/**
* By default, auto model generation is enabled for all modes. This function can be used to
* override that behavior.
* This function is only used when type is `models`.
*/
enabled?: (context: GenerationContext) => boolean;
parseResults: ParseGenerationResults;
type: (context: GenerationContext) => AutoModelGenerationType;
};
type ModelsAsDataLanguageAccessPathSuggestions = {

View File

@@ -1,4 +1,5 @@
import type { ModelsAsDataLanguage } from "../models-as-data";
import { AutoModelGenerationType } from "../models-as-data";
import { sharedExtensiblePredicates, sharedKinds } from "../shared";
import { Mode } from "../../shared/mode";
import { parseGenerateModelResults } from "./generate";
@@ -209,9 +210,33 @@ export const ruby: ModelsAsDataLanguage = {
},
];
},
parseResults: (queryPath, bqrs, modelsAsDataLanguage, logger, context) => {
// Only parse type models when automatically generating models
const typePredicate = modelsAsDataLanguage.predicates.type;
if (!typePredicate) {
throw new Error("Type predicate not found");
}
const typeTuples = bqrs[typePredicate.extensiblePredicate];
if (!typeTuples) {
return [];
}
return parseGenerateModelResults(
queryPath,
{
[typePredicate.extensiblePredicate]: typeTuples,
},
modelsAsDataLanguage,
logger,
context,
);
},
// Only enabled for framework mode when type models are hidden
enabled: ({ mode, config }) =>
mode === Mode.Framework && !config.showTypeModels,
type: ({ mode, config }) =>
mode === Mode.Framework && !config.showTypeModels
? AutoModelGenerationType.SeparateFile
: AutoModelGenerationType.Disabled,
},
accessPathSuggestions: {
queryConstraints: (mode) => ({

View File

@@ -54,7 +54,11 @@ import { telemetryListener } from "../common/vscode/telemetry";
import type { ModelingStore } from "./modeling-store";
import type { ModelingEvents } from "./modeling-events";
import type { ModelsAsDataLanguage } from "./languages";
import { createModelConfig, getModelsAsDataLanguage } from "./languages";
import {
AutoModelGenerationType,
createModelConfig,
getModelsAsDataLanguage,
} from "./languages";
import { runGenerateQueries } from "./generate";
import { ResponseError } from "vscode-jsonrpc";
import { LSPErrorCodes } from "vscode-languageclient";
@@ -710,10 +714,12 @@ export class ModelEditorView extends AbstractWebview<
return;
}
if (
autoModelGeneration.enabled &&
!autoModelGeneration.enabled({ mode, config: this.modelConfig })
) {
const autoModelType = autoModelGeneration.type({
mode,
config: this.modelConfig,
});
if (autoModelType === AutoModelGenerationType.Disabled) {
return;
}
@@ -734,6 +740,8 @@ export class ModelEditorView extends AbstractWebview<
queryConstraints: autoModelGeneration.queryConstraints(mode),
filterQueries: autoModelGeneration.filterQueries,
onResults: (queryPath, results) => {
switch (autoModelType) {
case AutoModelGenerationType.SeparateFile: {
const extensions = autoModelGeneration.parseResultsToYaml(
queryPath,
results,
@@ -742,6 +750,27 @@ export class ModelEditorView extends AbstractWebview<
);
extensionFile.extensions.push(...extensions);
break;
}
case AutoModelGenerationType.Models: {
const modeledMethods = autoModelGeneration.parseResults(
queryPath,
results,
modelsAsDataLanguage,
this.app.logger,
{
mode,
config: this.modelConfig,
},
);
this.addModeledMethodsFromArray(modeledMethods);
break;
}
default: {
assertNever(autoModelType);
}
}
},
cliServer: this.cliServer,
queryRunner: this.queryRunner,
@@ -761,6 +790,7 @@ export class ModelEditorView extends AbstractWebview<
return;
}
if (autoModelType === AutoModelGenerationType.SeparateFile) {
progress({
step: 4000,
maxStep: 4000,
@@ -777,6 +807,7 @@ export class ModelEditorView extends AbstractWebview<
await outputFile(filePath, fileContents);
void this.app.logger.log(`Saved generated model file to ${filePath}`);
}
},
{
cancellable: false,