langium
langium copied to clipboard
Make the `$container` type more precise in case of guard conditions
The following simple and artificial example uses guard conditions in order to switch between different cases (excerpt):
Teacher:
'teacher' name=ID values=Reused<true>;
Student:
'student' name=ID values=Reused<false>;
Reused<condition>:
<!condition> OneValue | <condition> TwoValues;
OneValue:
'values' value=ID;
TwoValues:
'values' valueOne=ID valueTwo=ID;
(The whole grammar with an instance can be found in the playground.)
For this grammar, Langium generates the following types in the ast.ts (excerpt):
export type Reused = OneValue | TwoValues;
export interface OneValue extends AstNode {
readonly $container: Student | Teacher;
readonly $type: 'OneValue';
value: string
}
export interface TwoValues extends AstNode {
readonly $container: Student | Teacher;
readonly $type: 'TwoValues';
valueOne: string
valueTwo: string
}
From my point of view, the types of the $container properties could be more precise, i.e. only Student for OneValue and only Teacher for TwoValues.
The current $container types are not wrong, but as a user of Langium, I would expect the following types, since the grammar clearly shows, that these types are enough:
export type Reused = OneValue | TwoValues;
export interface OneValue extends AstNode {
readonly $container: Student;
readonly $type: 'OneValue';
value: string
}
export interface TwoValues extends AstNode {
readonly $container: Teacher;
readonly $type: 'TwoValues';
valueOne: string
valueTwo: string
}
If you think this issue is worth an improvement, I am willing to work on this issue!
Yes for such clear cases it would make sense to restrict the container type.