Skip to content

Commit c37bd99

Browse files
authored
Merge pull request #3550 from github/koesie10/separate-file
Add auto-model generation mode without separate file
2 parents 1dac41d + fed30b6 commit c37bd99

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";
@@ -700,10 +704,12 @@ export class ModelEditorView extends AbstractWebview<
700704
return;
701705
}
702706

703-
if (
704-
autoModelGeneration.enabled &&
705-
!autoModelGeneration.enabled({ mode, config: this.modelConfig })
706-
) {
707+
const autoModelType = autoModelGeneration.type({
708+
mode,
709+
config: this.modelConfig,
710+
});
711+
712+
if (autoModelType === AutoModelGenerationType.Disabled) {
707713
return;
708714
}
709715

@@ -724,14 +730,37 @@ export class ModelEditorView extends AbstractWebview<
724730
queryConstraints: autoModelGeneration.queryConstraints(mode),
725731
filterQueries: autoModelGeneration.filterQueries,
726732
onResults: (queryPath, results) => {
727-
const extensions = autoModelGeneration.parseResultsToYaml(
728-
queryPath,
729-
results,
730-
modelsAsDataLanguage,
731-
this.app.logger,
732-
);
733-
734-
extensionFile.extensions.push(...extensions);
733+
switch (autoModelType) {
734+
case AutoModelGenerationType.SeparateFile: {
735+
const extensions = autoModelGeneration.parseResultsToYaml(
736+
queryPath,
737+
results,
738+
modelsAsDataLanguage,
739+
this.app.logger,
740+
);
741+
742+
extensionFile.extensions.push(...extensions);
743+
break;
744+
}
745+
case AutoModelGenerationType.Models: {
746+
const modeledMethods = autoModelGeneration.parseResults(
747+
queryPath,
748+
results,
749+
modelsAsDataLanguage,
750+
this.app.logger,
751+
{
752+
mode,
753+
config: this.modelConfig,
754+
},
755+
);
756+
757+
this.addModeledMethodsFromArray(modeledMethods);
758+
break;
759+
}
760+
default: {
761+
assertNever(autoModelType);
762+
}
763+
}
735764
},
736765
cliServer: this.cliServer,
737766
queryRunner: this.queryRunner,
@@ -751,22 +780,24 @@ export class ModelEditorView extends AbstractWebview<
751780
return;
752781
}
753782

754-
progress({
755-
step: 4000,
756-
maxStep: 4000,
757-
message: "Saving generated models",
758-
});
783+
if (autoModelType === AutoModelGenerationType.SeparateFile) {
784+
progress({
785+
step: 4000,
786+
maxStep: 4000,
787+
message: "Saving generated models",
788+
});
759789

760-
const fileContents = `# This file was automatically generated from ${this.databaseItem.name}. Manual changes will not persist.\n\n${modelExtensionFileToYaml(extensionFile)}`;
761-
const filePath = join(
762-
this.extensionPack.path,
763-
"models",
764-
`${this.language}${GENERATED_MODELS_SUFFIX}`,
765-
);
790+
const fileContents = `# This file was automatically generated from ${this.databaseItem.name}. Manual changes will not persist.\n\n${modelExtensionFileToYaml(extensionFile)}`;
791+
const filePath = join(
792+
this.extensionPack.path,
793+
"models",
794+
`${this.language}${GENERATED_MODELS_SUFFIX}`,
795+
);
766796

767-
await outputFile(filePath, fileContents);
797+
await outputFile(filePath, fileContents);
768798

769-
void this.app.logger.log(`Saved generated model file to ${filePath}`);
799+
void this.app.logger.log(`Saved generated model file to ${filePath}`);
800+
}
770801
},
771802
{
772803
cancellable: false,

0 commit comments

Comments
 (0)