-
Notifications
You must be signed in to change notification settings - Fork 80
Description
Langium version: 3.3.1
Package name: https://registry.npmjs.org/langium/-/langium-3.3.1.tgz
Synopsis:
If a non-terminal has an alternative of a keyword property and an unassigned rule call, and the unassigned rule call refers to a non-terminal with the same keyword property, then the .ts code won't compile.
Context:
We need to represent the type system of our domain in our Langium grammar. Properly representing the subtype hierarchy is important for our application. Simplified example: example.langium.txt
Generating the attached example.langium yields typescript modules with syntax errors:
Interface 'BaseNumberType' incorrectly extends interface 'BasePrimitiveType'.
Types of property 'typeStr' are incompatible.
Type '"base:Float" | "base:Int"' is not assignable to type '"base:Bool" | "base:String"'.
Type '"base:Float"' is not assignable to type '"base:Bool" | "base:String"'.
Expected behavior: The generated TS code should be compilable.
One possible approach for this would be to let the string literal narrowing include the values from unassigned rule calls (as it already does for $type), e.g.:
export interface BasePrimitiveType extends AstNode {
readonly $type: 'BaseNumberType' | 'BasePrimitiveType';
typeStr: 'base:Bool' | 'base:String' | 'base:Float' | 'base:Int';
}
As a workaround, we tried adding "infers" to our grammar:
example_with_infers.langium.txt
But for longer rule call chains, this doesn't work either:
Interface 'BaseExceptionType' incorrectly extends interface 'BaseComplexType'.
Types of property 'typeStr' are incompatible.
Type '"io:FileNotFoundException" | "io:FlashPermissionException"' is not assignable to type '"base:Exception" | "base:List" | "base:Map" | "base:Semaphore" | "base:TypeException" | "io:File"'.