Skip to content

Commit fed30b6

Browse files
committed
Add auto-model generation mode without separate file
1 parent 8a3a6d7 commit fed30b6

File tree

3 files changed

+106
-31
lines changed

3 files changed

+106
-31
lines changed

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,34 @@ type ParseResultsToYaml = (
105105
logger: BaseLogger,
106106
) => ModelExtension[];
107107

108+
export enum AutoModelGenerationType {
109+
/**
110+
* Auto model generation is disabled and will not be run.
111+
*/
112+
Disabled = "disabled",
113+
/**
114+
* The models are generated to a separate file (suffixed with .model.generated.yml).
115+
*/
116+
SeparateFile = "separateFile",
117+
/**
118+
* The models are added as a model in the model editor, but are not automatically saved.
119+
* The user can view them and choose to save them.
120+
*/
121+
Models = "models",
122+
}
123+
108124
type ModelsAsDataLanguageAutoModelGeneration = {
109125
queryConstraints: (mode: Mode) => QueryConstraints;
110126
filterQueries?: (queryPath: string) => boolean;
127+
/**
128+
* This function is only used when type is `separateFile`.
129+
*/
111130
parseResultsToYaml: ParseResultsToYaml;
112131
/**
113-
* By default, auto model generation is enabled for all modes. This function can be used to
114-
* override that behavior.
132+
* This function is only used when type is `models`.
115133
*/
116-
enabled?: (context: GenerationContext) => boolean;
134+
parseResults: ParseGenerationResults;
135+
type: (context: GenerationContext) => AutoModelGenerationType;
117136
};
118137

119138
type ModelsAsDataLanguageAccessPathSuggestions = {

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ModelsAsDataLanguage } from "../models-as-data";
2+
import { AutoModelGenerationType } from "../models-as-data";
23
import { sharedExtensiblePredicates, sharedKinds } from "../shared";
34
import { Mode } from "../../shared/mode";
45
import { parseGenerateModelResults } from "./generate";
@@ -209,9 +210,33 @@ export const ruby: ModelsAsDataLanguage = {
209210
},
210211
];
211212
},
213+
parseResults: (queryPath, bqrs, modelsAsDataLanguage, logger, context) => {
214+
// Only parse type models when automatically generating models
215+
const typePredicate = modelsAsDataLanguage.predicates.type;
216+
if (!typePredicate) {
217+
throw new Error("Type predicate not found");
218+
}
219+
220+
const typeTuples = bqrs[typePredicate.extensiblePredicate];
221+
if (!typeTuples) {
222+
return [];
223+
}
224+
225+
return parseGenerateModelResults(
226+
queryPath,
227+
{
228+
[typePredicate.extensiblePredicate]: typeTuples,
229+
},
230+
modelsAsDataLanguage,
231+
logger,
232+
context,
233+
);
234+
},
212235
// Only enabled for framework mode when type models are hidden
213-
enabled: ({ mode, config }) =>
214-
mode === Mode.Framework && !config.showTypeModels,
236+
type: ({ mode, config }) =>
237+
mode === Mode.Framework && !config.showTypeModels
238+
? AutoModelGenerationType.SeparateFile
239+
: AutoModelGenerationType.Disabled,
215240
},
216241
accessPathSuggestions: {
217242
queryConstraints: (mode) => ({

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

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ import { telemetryListener } from "../common/vscode/telemetry";
5454
import type { ModelingStore } from "./modeling-store";
5555
import type { ModelingEvents } from "./modeling-events";
5656
import type { ModelsAsDataLanguage } from "./languages";
57-
import { createModelConfig, getModelsAsDataLanguage } from "./languages";
57+
import {
58+
AutoModelGenerationType,
59+
createModelConfig,
60+
getModelsAsDataLanguage,
61+
} from "./languages";
5862
import { runGenerateQueries } from "./generate";
5963
import { ResponseError } from "vscode-jsonrpc";
6064
import { LSPErrorCodes } from "vscode-languageclient";
@@ -710,10 +714,12 @@ export class ModelEditorView extends AbstractWebview<
710714
return;
711715
}
712716

713-
if (
714-
autoModelGeneration.enabled &&
715-
!autoModelGeneration.enabled({ mode, config: this.modelConfig })
716-
) {
717+
const autoModelType = autoModelGeneration.type({
718+
mode,
719+
config: this.modelConfig,
720+
});
721+
722+
if (autoModelType === AutoModelGenerationType.Disabled) {
717723
return;
718724
}
719725

@@ -734,14 +740,37 @@ export class ModelEditorView extends AbstractWebview<
734740
queryConstraints: autoModelGeneration.queryConstraints(mode),
735741
filterQueries: autoModelGeneration.filterQueries,
736742
onResults: (queryPath, results) => {
737-
const extensions = autoModelGeneration.parseResultsToYaml(
738-
queryPath,
739-
results,
740-
modelsAsDataLanguage,
741-
this.app.logger,
742-
);
743-
744-
extensionFile.extensions.push(...extensions);
743+
switch (autoModelType) {
744+
case AutoModelGenerationType.SeparateFile: {
745+
const extensions = autoModelGeneration.parseResultsToYaml(
746+
queryPath,
747+
results,
748+
modelsAsDataLanguage,
749+
this.app.logger,
750+
);
751+
752+
extensionFile.extensions.push(...extensions);
753+
break;
754+
}
755+
case AutoModelGenerationType.Models: {
756+
const modeledMethods = autoModelGeneration.parseResults(
757+
queryPath,
758+
results,
759+
modelsAsDataLanguage,
760+
this.app.logger,
761+
{
762+
mode,
763+
config: this.modelConfig,
764+
},
765+
);
766+
767+
this.addModeledMethodsFromArray(modeledMethods);
768+
break;
769+
}
770+
default: {
771+
assertNever(autoModelType);
772+
}
773+
}
745774
},
746775
cliServer: this.cliServer,
747776
queryRunner: this.queryRunner,
@@ -761,22 +790,24 @@ export class ModelEditorView extends AbstractWebview<
761790
return;
762791
}
763792

764-
progress({
765-
step: 4000,
766-
maxStep: 4000,
767-
message: "Saving generated models",
768-
});
793+
if (autoModelType === AutoModelGenerationType.SeparateFile) {
794+
progress({
795+
step: 4000,
796+
maxStep: 4000,
797+
message: "Saving generated models",
798+
});
769799

770-
const fileContents = `# This file was automatically generated from ${this.databaseItem.name}. Manual changes will not persist.\n\n${modelExtensionFileToYaml(extensionFile)}`;
771-
const filePath = join(
772-
this.extensionPack.path,
773-
"models",
774-
`${this.language}${GENERATED_MODELS_SUFFIX}`,
775-
);
800+
const fileContents = `# This file was automatically generated from ${this.databaseItem.name}. Manual changes will not persist.\n\n${modelExtensionFileToYaml(extensionFile)}`;
801+
const filePath = join(
802+
this.extensionPack.path,
803+
"models",
804+
`${this.language}${GENERATED_MODELS_SUFFIX}`,
805+
);
776806

777-
await outputFile(filePath, fileContents);
807+
await outputFile(filePath, fileContents);
778808

779-
void this.app.logger.log(`Saved generated model file to ${filePath}`);
809+
void this.app.logger.log(`Saved generated model file to ${filePath}`);
810+
}
780811
},
781812
{
782813
cancellable: false,

0 commit comments

Comments
 (0)